Swift 是否放弃了实例变量的下划线前缀约定,例如 _window?如果是这样,为什么?
Apple 仍然在其 Xcode 样板代码中使用
_
作为 non-public
变量的约定。你会看到这样的模式:
class Foo {
var _bar : Bar? = nil
var bar : Bar {
if _bar == nil {
/* compute some stuff */
_bar = Bar (/* ... */)
}
return _bar!
}
}
其中对属性的访问意味着通过
bar
计算属性。您可以在 Apple CoreData 模板中找到此内容。
在 Objective-C 中,当你声明一个属性时,从 clang 3.2 开始,
@synthesize
会自动为你创建 getter 和 setter。因此,属性 @synthesize
的默认 foo
看起来像这样:
@synthesize foo = _foo
因此
_foo
将成为 iVar。换句话说,你可以自己完成 @synthesize 并将 iVar 命名为任何你喜欢的名字:
@synthesize foo = myiVarFoo
所以在这种情况下没有“_”
现在在 Swift 中,来自 文档:
Swift 将这些概念统一到一个属性声明中。 Swift 属性没有相应的实例变量,并且不能直接访问属性的后备存储。
因此从文档中可以清楚地看出,swift 没有相应的实例变量,因此不再需要“_”。
下划线前缀是为了避免将实例变量
_foo
与其 getter foo
混淆。
在 swift 中,ivars 和 getter 之间没有这样的区别。相反,您只有属性,因此不需要
_
约定。
答案是否定的,因为 Swift 中目前没有“实例变量”。仅属性(存储属性和计算属性)。
我想说这个 _underscoreName 约定已被删除(尽管某些 Apple 模板仍然保留它)。
Swift 的“惰性存储属性”使 _这些变得不必要。这篇文章:
http://mikebuss.com/2014/06/22/lazy-initialization-swift/
解释得很好。
我使用前导下划线来表示私有符号。
是的,下划线一开始确实会妨碍可读性,但在理解和可维护性方面会带来宝贵的回报。
例如:
final class SomeClass
{
fileprivate let _kMagicNumber: CGFloat = 3.14
fileprivate struct _PrivateInfo
{
let foo: Int
let bar: String
}
fileprivate var _privateInfo: _PrivateInfo
fileprivate func _setup(with info: _PrivateInfo) { ... }
}
等等
一眼就能看出哪些元素属于哪里。
您不需要按住选项单击或执行“这属于谁?”跳舞。
代码理解不应依赖于 IDE 的功能。有时(GitHub、原始文本文件)IDE 不可用。
我理解“这不符合惯例”的论点。但惯例并不是写在石碑上的。 Swift 正在迅速发展,我们对它的使用也是如此。
如果 Swift 团队明天要为私有符号生成注释语法,我会使用它。但在那之前...
既然我已经拿出了我的肥皂盒,请为您的扩展添加前缀。
考虑这个片段:
let color = "#ff7733".hexColor
“hexColor”从哪里来?你自己的代码? Swift 标准库?基础?优基特? (哈!)CocoaPod?谁知道?
(经验丰富的 CocoaPods 用户会知道,每隔一个开源库都会实现一个“hexColor”属性。这会带来所有问题。)
因此,给定一个公司或项目名称,例如“双重秘密缓刑”,请考虑使用:
let color = "#ff7733".dsp_hexColor
最后强烈推荐《Writing Solid Code》和《Code Complete》这两本书。
前缀私有变量的约定远远早于 ObjC(奇怪的)属性综合概念的约定。清晰性是这种前缀的最初原因,而不是区分,尽管出于显而易见的原因公开不带下划线的 public getter 是有用且常见的。 IMO,ObjC 道具合成只是在作品中放了一个大而肥的活动扳手,让每个人都感到困惑......
如果您想要私人合成财产怎么办?为了给你的私有合成属性添加下划线前缀,你需要一个 double 下划线支持变量。苹果特别警告不要使用双下划线,这会造成混乱。我们应该费心在内部使用合成属性还是坚持使用支持变量(它仍然有下划线并且显然是私有的)?我们应该停止区分私有变量和公共变量吗?为什么??
在实践中,当且仅当他们想要智能时,人们才会使用类内部的合成版本作为一种智能设置器 - 但这打破了封装的理想 - 选择是否使用所需的合成设置器对幕后发生的事情的先验知识。
同时,正如上面所指出的,苹果的内部代码仍然使用该约定,有时对于合成属性也使用IIRC。对于 swift 属性来说,它们仍然如此!但不一致......你的语言设计政策令人困惑的最大证据是当你自己的开发人员没有一致地使用它时!
清晰是最初的动机,而且效果很好。我说:
...对于私有变量和方法:)
(P.S. Dart 甚至将其作为实际语言约定来代替
private
关键字!)