静态const与extern const有何不同?

在我的iOS / Objective C项目中,我经常使用带有API密钥等的constants.h文件。 直到今天,我一直将我的常量声明为static const如下所示:

 static NSString * const kAPIKey = @"wembvkejrvb43789gvbiu2bvfake"; 

这工作正常,但有一个不幸的缺点,我只能创建基元和NSString文字的常量。 其他对象(如UIColor对象)无法存储在此常量中, 因为它们无法使用静态文字语法进行初始化 (我的理解,需要引用)。

在阅读了一些C ++文档后,我理解了一些事情:

  • static是不必要的,因为const是隐式静态的。
  • 调用NSString * const x实际上是在x中声明一个常量且不可变的值。 我无法更改值,但可以更改x指向的值。
  • 该const具有内部链接,意味着该值立即定义(在编译时可以推测)。

这些结论是否正确?

extern const如何不同? 我假设它们是外部链接的(因此是extern关键字)。 它们是在运行时定义的吗? 我可以创建某种动态 extern const ,可以使用类方法返回的值进行设置吗?

例如,我想创建一个包含UIColor值的全局范围常量。 我想使用[UIColor colorWithRed:green:blue:alpha:]类方法构造此颜色值。 这显然不适用于我一直在使用的内部链接常量(我假设因为它发生在编译时) – 但是可能使用外部常量,可能在+initialize方法中设置?

任何有关此行为细节的详细说明都会非常有用。

静态是不必要的,因为const是隐式静态的。

不,那不是真的。

在文件范围内使用static (即在任何方法或函数之外)意味着该变量仅在该文件中可见。

extern表示变量在某个其他文件中定义。

const表示无法修改变量。

考虑字符串。 通常,您将拥有一个实现文件(名称以.m结尾),它定义了一些常量字符串指针:

 NSString *const SomeString = @"some string"; 

您可能希望从其他文件中使用相同的常量。 如果是这样,您可以在标题中添加一个声明(名称以.h结尾)文件,向编译器解释该变量是在其他地方定义的:

 extern NSString *const SomeString; 

这将允许您在任何导入头文件的文件中使用SomeString 。 另一方面,您可能认为您绝对希望在实现文件外部使用常量。 在这种情况下,您可以将其声明为static (在实现文件中):

 static NSString *const SomeString = @"some string"; 

这会阻止它从文件外部使用。

调用NSString * const x实际上是在x中声明一个常量且不可变的值。 我无法更改值,但可以更改x指向的值。

是的,它声明指针x是常量 – 你不能改变它。 如果它实际上是NSString ,您也无法更改它指向的值,因为实例NSString不可变。

该const具有内部链接,意味着该值立即定义(在编译时可以推测)。

我将采取第5个 – 我不确定编译器如何处理常量字符串。 不过,我认为将其用作心理模型是安全的。 在任何情况下,字符串都将在您的代码使用之前定义。

在您的特定编程问题上,如何创建编译时定义的颜色对象:您不能,因为除了少数语言提供文字语法之外,对象是在运行时创建的。

但是你仍然可以在运行时优雅地完成它,而不会增加全局范围,就像sdk所做的那样……

 @interface UIColor (RainbowAddition) + (UIColor *)chartruseColor; @end @implementation UIColor (RainbowAddition) + (UIColor *)chartruseColor { // bonus: this is really chartruse... according to the internet return [self colorWithRed:0.5 green:1.0 blue:0.0 alpha:1.0]; } @end 

http://cloford.com/resources/colours/500col.htm

Objective-C是C的纯扩展,C ++不是。

在全球范围内:

  • 在C(和Objective-C)中编写const相当于extern const (外部链接);
  • 在C ++中编写const相当于static const (内部链接)。

在C(和Objective-C)和C ++中,要创建一个全局范围的const你只需要在一个源文件中定义它,就像extern const TYPE identifier = VALUE; 并声明它(通常在头文件中),如: extern const TYPE identifier; (读它:我在全球联动级别的其他地方定义了这个const)。