Objective C - 为什么常量以k开头

45

为什么我看到的所有示例中常量都以k开头?我应该在头文件还是.m文件中使用#define定义常量?

我是Objective-C的新手,也不懂C语言。有没有一些针对这种情况的教程可以解释这些内容呢?


1
顺便提一下,有一本关于Objective-C的优秀教程,它并不假设你已经了解C语言:《Objective-C编程》由Stephan G. Kochan所著,可在InformIT.com上获取。http://www.informit.com/store/programming-in-objective-c-9780321887283 - Basil Bourque
6个回答

44
在IT技术中,以“k”开头的常量命名是Mac OS X之前的一种遗留习惯。实际上,我认为这种做法甚至可能源自很久以前的时期,当时 Mac OS 主要用 Pascal 编写,而主流的开发语言也是 Pascal。在C语言中,使用 #define 宏定义常量通常采用全部大写字母,而不是以“k”为前缀。
至于在哪里使用 #define 宏定义常量:将它们定义在需要使用它们的地方。如果你希望使用您的代码的人使用该常量,请将其放在头文件中;如果该常量仅在内部使用,请将其放在 .m 文件中。

7
有趣的是,Google的代码风格指南也要求常量以“k”开头。当那些不喜欢匈牙利命名法的人使用这种约定时,我感到很有趣。 :) - i_am_jorf
我决定将我的常量放在.m文件中,在# imports之后和@ implementation之前。 - mk12
你不能也为常量创建一个 .h 文件,然后使用 extern const something something 吗?这是如何工作的? - mk12
使用那种方法有什么优势吗? - mk12
8
#define 基本上是一种搜索和替换操作;因此,如果你使用 #define MYCONST @"My Constant",那么每次使用 MYCONST 时都会分配一个字符串。但如果你使用 extern NSString * const MYCONST = @"My Constant";,则该字符串只会被分配一次,并且所有对 MYCONST 的使用都指向同一个字符串。对于其他使用 #define 定义的数据类型(例如 #define MYCONST 4.0),这些区别并不重要。 - mipadi
显示剩余2条评论

9
当前苹果公司的建议中,关于命名常量并不包括‘k’前缀,但是许多组织采用了这个约定并仍在使用它,因此你仍然会经常看到它。请参考:苹果公司的最新建议以及命名常量的规范

8

这个“k”代表什么意思的问题在这个问题中得到了回答。

如果你想让除了那个特定的.m文件之外的其他文件也使用这些常量,你必须把常量放在头文件中,因为它们无法导入.m文件。

你可能会对Cocoa Dev Central的Cocoa程序员的C教程感兴趣。它解释了很多核心概念。


6
k 前缀来自于许多开发者喜欢在他们的代码中使用 匈牙利命名法 的时代。在匈牙利命名法中,每个变量都有一个前缀,告诉你它是什么类型。 pSize 将是一个名为 "size" 的指针,而 iSize 将是一个名为 "size" 的整数。只看变量名,你就知道它的类型。这在没有现代 IDE 可以随时显示任何变量类型的情况下非常有用,否则你总是需要搜索声明才能知道它。追随当时的潮流,Apple 想要为所有常量设置一个共同的前缀。
好的,为什么不用像“常数”一样的c呢?因为在匈牙利表示法中,c已经被使用了,c代表“计数器”(cApple表示“苹果的数量”)。同样的问题也出现在class上,因为它是许多语言中的关键字,那么你如何命名指向类的变量呢?你会发现有大量的代码将该变量命名为klass,因此选择了kk表示“konstant”。在许多语言中,这个单词实际上以k开头,请看这里
关于您的第二个问题:如果可以避免,您根本不应该使用#define来定义常量,因为#define是无类型的。
const int x = 10;           // Type is int
const short y = 20;         // Type is short
const uint64_t z = 30;      // Type is for sure UInt64
const double d = 5000;      // Type is for sure double
const char * str = "Hello"; // Type is for sure char *

#define FOO 90

“FOO”是什么类型?它是某种数字。但是什么类型的数字?到目前为止,可以是任何类型或根本没有类型。类型取决于您在代码中如何使用“FOO”。此外,如果您有一组固定的数字,请使用“枚举”,因为编译器可以验证您是否使用了有效值,并且枚举值始终是常量。
如果您必须使用define,那么无论在哪里定义它都没有关系。头文件是多个代码文件之间共享的文件,因此,如果您需要在多个地方使用相同的define,则将其编写到头文件中,并在需要使用该define的任何位置包含该头文件。您编写到代码文件中的内容仅在该代码文件中可见,除非非静态函数和Obj-C类默认情况下都是全局可见的。但是,除非一个函数在头文件中声明并且该头文件被包含到要使用该函数的代码文件中,否则编译器将不知道这个函数的样子(它期望什么参数,返回什么结果值),因此它不能检查任何东西,并且必须依赖于您正确调用它(通常会导致它创建一个警告)。除非您告诉当前代码文件至少这个名称是一个类的名称,否则根本无法使用Obj-C类,但是如果您想对该类进行实际操作(而不仅仅是传递它),则编译器需要知道类的接口,这就是为什么接口放入头文件中的原因(如果该类仅在当前代码文件中使用,则将接口和实现编写到文件中也是合法的,并且可以正常工作)。

3

"k"代表“konvention”,这只是一种惯例。

您可以在任何地方放置#define,可以放在头文件中,在.m文件的顶部或在使用它的.m文件旁边。只需将其放置在使用它的任何代码之前即可。

Xcode工具套件提供的“Objective-C入门”文档实际上非常好。多读几遍(我喜欢每2到5年重新阅读一次)。

然而,无论是它还是我所知道的任何C书籍都无法回答这些特定问题。答案通过经验变得明显。


1

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接