开发者

What does the 'a' prefix represent in aString?

I'm just looking at NSString.h and wonder why some method declaration args use (NSStr开发者_如何学编程ing *)string; while others use (NSString *)aString.

What are the conventions practiced here?


It's simply the indefinite article "a", as in the parameter is "a string". It appears in some methods to make them read a little more like English. For example, compare:(NSString*)aString reads as "compare a string". The official naming conventions for method parameters are rather basic; they show the use of the indefinite article but don't explain why.


The object-oriented half of Objective-C comes from Smalltalk, and so does this convention.

Smalltalk was originally designed to be used by children, without them having to learn programming. Later on that goal was relaxed a bit and it was more targeted at domain experts for doing end user programming. In both cases, the language designers felt that the language should be a compelling user interface, and thus they paid very close attention to even the smallest details, like the naming of parameters in method signatures.

Method signatures themselves are fairly unusual in Smalltalk (and Objective-C), in that the arguments and parameters are not written after the name (as in pretty much every other language ever invented), but rather the name of the method gets broken up into pieces and the arguments and parameters go between them. This makes for some strange looking method names, but when you read the entire signature with the arguments or parameters, then it reads almost like a sentence in the domain jargon of whatever domain that particular method operates in.

So, in some run of the mill OO language, a method for storing a value at a particular index in an array might look like this:

store(i, obj)

or even worse, like this:

public void store(int i, T obj)

or this:

store(self, i, obj)

er even this (from my favorite language):

[]=(i, obj)

(How do you even pronounce that?)

and might be called like this:

ary.store(3, "Hello")

or this:

ary[3] = "Hello"

or maybe with little bit less punctuation (in Io and Ioke, for example):

ary store(3, "Hello")

In Smalltalk, the signature looks like this:

at: anInteger put: anObject

and it is called like this:

anArray at: 3 put: "Hello".

If you read the signature out loud, it becomes clear that there simply has to be an indefinite article there, otherwise it just wouldn't read right.

Note some of the differences: in the mainstream versions, parameters are only distinguished by their positions. So, in order to figure out what they mean, you give them descriptive names. But when you actually call the method, those descriptive names are gone, because the parameters get replaced with the arguments. (And yes, I am well aware that i isn't exactly a descriptive name. If you want to, you can repeat the experiment with something like copy(source, destination) and copyFrom: aDirectory to: anotherDirectory).

In the Smalltalk example, however, the semantics of the parameter are encoded in the method name, thus freeing up the parameter name for other usages. In this case, type annotations (since Smalltalk is implicitly typed) or, well, basically some form of Hungarian Notation. Also, when you call the method, the encoded meaning is still there in the method name. (In the example above, when you read copy(a, b), you don't know whether this is copying from a to b or the other way round, but with copyFrom: a to: b. there is no ambiguity. You could fix that by renaming the method: copyFromTo(a, b), but that doesn't read very well, either.)

Now, in Objective-C, all of this gets a little lost, because of the type annotations. Compare these two signatures, which basically describe the same method:

at: anInteger put: anObject
- (void)insertObject:(id)anObject atIndex:(NSUInteger)index

Somehow, the "read it out loud as an English sentence" part got lost, but the "an" prefix for anObject is still there.

Anyway, to make a long story short: the reason for those prefixes has to do with Objective-C's heritage.


This is often done in setters and other method declarations to avoid name clashes with instance variables of the class. Often in setters you'll see:

variable = aVariable


'aString' is just the name of the input variable, internal to the method. Most probably the function already uses a variable called 'string' so it uses 'aString' (like 'a string' or 'some string') to distinguish between them, while keeping the name general. That's what I believe anyway.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜