Stu*_*art 95 methods properties semantics swift
在Swift WWDC会话简介中,description
演示了一个只读属性:
class Vehicle {
var numberOfWheels = 0
var description: String {
return "\(numberOfWheels) wheels"
}
}
let vehicle = Vehicle()
println(vehicle.description)
Run Code Online (Sandbox Code Playgroud)
选择上述方法而不是使用方法有任何影响:
class Vehicle {
var numberOfWheels = 0
func description() -> String {
return "\(numberOfWheels) wheels"
}
}
let vehicle = Vehicle()
println(vehicle.description())
Run Code Online (Sandbox Code Playgroud)
在我看来,你选择只读计算属性的最明显的原因是:
description
类的属性是有意义的,而不是它执行的动作.显然,上面的例子过于简单,但还有其他充分理由选择其中一个吗?例如,是否有某些功能或属性的功能可以指导您决定使用哪些功能?
NB乍一看,这似乎是一个非常常见的OOP问题,但我很想知道任何特定于Swift的功能,这些功能可以指导使用这种语言时的最佳实践.
Joh*_*rug 51
在我看来,这主要是风格问题:我非常喜欢使用属性:属性; 意味着您可以获得和/或设置的简单值.我在实际工作时使用函数(或方法).也许必须从磁盘或数据库中计算或读取某些东西:在这种情况下,我使用一个函数,即使只返回一个简单的值.这样我就可以很容易地看到一个电话是便宜的(属性)还是可能是昂贵的(函数).
当Apple发布一些Swift编码约定时,我们可能会更加清晰.
onm*_*133 12
好吧,你可以申请Kotlin的建议https://kotlinlang.org/docs/reference/coding-conventions.html#functions-vs-properties.
在某些情况下,没有参数的函数可以与只读属性互换.尽管语义相似,但是对于何时优先选择彼此,存在一些风格约定.
在基础算法时首选属性而不是函数:
- 不扔
- 复杂度很便宜(或在第一次运行时计算)
- 通过调用返回相同的结果
小智 11
虽然计算属性与方法的问题一般是困难和主观的,但目前在Swift的案例中有一个重要的论点,即偏好属性的方法.你可以使用Swift中的方法作为纯函数,这对于属性来说是不正确的(从Swift 2.0 beta开始).这使得方法更加强大和有用,因为它们可以参与功能组合.
func fflat<A, R>(f: (A) -> () -> (R)) -> (A) -> (R) {
return { f($0)() }
}
func fnot<A>(f: (A) -> Bool) -> (A) -> (Bool) {
return { !f($0) }
}
extension String {
func isEmptyAsFunc() -> Bool {
return isEmpty
}
}
let strings = ["Hello", "", "world"]
strings.filter(fnot(fflat(String.isEmptyAsFunc)))
Run Code Online (Sandbox Code Playgroud)
由于运行时是相同的,因此该问题也适用于Objective-C.我会说,你得到的属性
readwrite
didSet
进行更改通知至于特定于Swift的东西,我唯一的例子是你可以@lazy
用于一个属性.
在只读情况下,计算出的属性应该不被认为是语义上等同于一个方法,即使他们的行为相同,因为下降的func
声明模糊包含量之间的区别状态的实例是仅仅和数量的功能的状态。您可以节省()
在调用站点上的输入,但可能会使代码变得不清晰。
作为一个简单的例子,考虑以下向量类型:
struct Vector {
let x, y: Double
func length() -> Double {
return sqrt(x*x + y*y)
}
}
Run Code Online (Sandbox Code Playgroud)
通过将长度声明为方法,很明显它是状态的函数,它仅取决于x
和y
。
另一方面,如果您要表示length
为计算属性
struct VectorWithLengthAsProperty {
let x, y: Double
var length: Double {
return sqrt(x*x + y*y)
}
}
Run Code Online (Sandbox Code Playgroud)
那么当你在你的IDE点选项卡完成上的一个实例VectorWithLengthAsProperty
,它看起来好像x
,y
,length
是平起平坐,这是不正确概念的属性。