В моих проектах iOS/Objective C у меня часто есть файл constants.h с ключами API и т. Д. До сих пор я был объявляя свои константы, как static
const
так:Как статический const отличается от extern const?
static NSString * const kAPIKey = @"wembvkejrvb43789gvbiu2bvfake";
Это прекрасно работает, но с неудачной нижней стороной, что я могу только создать константы для примитивов и NSString литералов, по существу. Другие объекты, такие как объекты UIColor, не могут быть сохранены в этой константе , поскольку они не могут быть инициализированы синтаксисом статического литерала (мое понимание, требуется ссылка).
После прочтения некоторых докторов C++, я понимаю несколько вещей:
static
является ненужным, так какconst
неявно статичным.- Вызов
NSString * const x
фактически объявляет постоянное и неизменяемое значение в x. Я не могу изменить значение, но могу изменить то, на что указывает x. - Этот const имеет внутренний linkage, что означает, что значение определено сразу (предположительно во время компиляции).
Правильно ли эти выводы?
Каким образом extern const
отличается? Я предполагаю, что они связаны извне (таким образом, ключевое слово extern). Определены ли они во время выполнения? Могу ли я создать своего рода динамическийextern const
, который может быть установлен со значением, возвращаемым методом класса?
Например, я хотел бы создать константу с глобальным охватом, содержащую значение UIColor. Я хотел бы построить это значение цвета, используя метод класса [UIColor colorWithRed:green:blue:alpha:]
. Это явно не работает с внутренне связанными константами, которые я использовал (я предполагаю, потому что это происходит во время компиляции), но возможно ли использование внешней константы, возможно, настроенной в методе +initialize
?
Любое уточнение деталей такого поведения было бы очень полезно.
Если 'static' limits scope и' extern' означает, что переменная определена в другом месте, мне даже не нужна 'extern' для глобальной константы? Я могу использовать 'NSString * const SomeString = @" Some String "' в заголовке и получить доступ к SomeString из любого файла, который импортирует этот заголовок?Иными словами, для глобальных констант требуется 'extern'? – cdstamper
Если вы это сделаете (определите 'SomeString' в заголовке), вы получите ошибки в отношении нескольких определений, если заголовок включен в более чем один файл реализации. 'extern' дает вам способ объявить о существовании переменной, которая определена в другом месте, так что объявление может быть импортировано во многие файлы, но' SomeString' определяется только * *. – Caleb
Очень интересно. Поэтому мой шаблон 'static const' работал только потому, что я объявлял их вне любого класса в пустом файле заголовка, который затем был включен в другое место. Константы 'extern' всегда определяются во время компиляции с использованием принятых литералов или есть способ создать« динамическую »константу (возможно, определенную в + инициализации). – cdstamper