Swift 快速统一存取原则
斯威夫特是否支持该计划?就我所知,以下情况表明情况并非如此:Swift 快速统一存取原则,swift,Swift,斯威夫特是否支持该计划?就我所知,以下情况表明情况并非如此: @objc protocol CounterDataSource { optional func incrementForCount(count: Int) -> Int optional var fixedIncrement: Int { get } } class Counter { var count = 0 var dataSource: CounterDataSource? f
@objc protocol CounterDataSource {
optional func incrementForCount(count: Int) -> Int
optional var fixedIncrement: Int { get }
}
class Counter {
var count = 0
var dataSource: CounterDataSource?
func increment() {
if let amount = dataSource?.incrementForCount?(count) {
count += amount
} else if let amount = dataSource?.fixedIncrement {
count += amount
}
}
}
incrementForCount
是一个函数,必须以不同的方式访问(作为“可选”实现方法),对吗?我认为这个问题误解了关于统一访问原则的文章,我甚至不确定协议如何适合这里的讨论
这篇文章不一定特别清楚,但有两个关键点:
Person
,它有两个我们关心的属性——年龄和生日
此类有两种可能的实现:
class Person {
let birthDate: NSDate
var age: Int {
NSCalendar.currentCalendar().components(NSCalendarUnit.CalendarUnitYear, fromDate: birthDate, toDate: NSDate(), options: nil).year
}
init(birthDate: NSDate) {
self.birthDate = birthDate
}
}
或者
在一种情况下,我们有一个计算的年龄,在另一种情况下,我们有一个存储的年龄
但在这两种情况下,我们都以相同的方式访问它们
如果第一种情况下的computed属性被函数替换为:calculateAge()->Int
调用方不应该关心年龄是根据出生日期计算的还是存储的属性。Swift拥有允许开发人员在不违反统一访问原则的情况下编写代码的工具
此外,我们在开发iOS和OS X应用程序时使用的框架在遵守统一访问原则方面做得很好。方法和属性访问器从不使用get
或calculate
前缀命名。属性可以实现为计算属性(或者,显然是存储属性)。方法可以进行计算,也可以简单地返回存储的变量。没有什么能阻止这一切
为完整起见,考虑到上述两个Person
实现,违反统一访问原则的情况如下所示:
class Person {
let birthDate: NSDate
var calculateAge: Int {
NSCalendar.currentCalendar().components(NSCalendarUnit.CalendarUnitYear, fromDate: birthDate, toDate: NSDate(), options: nil).year
}
init(birthDate: NSDate) {
self.birthDate = birthDate
}
}
或者
那么如果它支持,你会为此编写什么代码呢?链接中的描述只指向Swift的计算属性。“统一访问”还需要什么?要么我被这个问题弄糊涂了,要么提问者对有关统一访问原则的链接文章的解释与我大不相同。斯威夫特对此表示支持。当您访问实例的属性时,您的代码不知道它是存储的还是计算的。协议中的可选功能是不同的,不会影响这一点。它们主要是为了与Obj-C兼容而存在的,但为协议提供了一种只需要部分实现的方法。它们的访问方式不同,但一致。@Darko我同意,链接只是代码片段的来源。但是正如您在示例代码中看到的,属性fixedIncrement的访问方式与函数不同。该函数需要一个额外的“?”。这是否违反了统一访问原则?不,我甚至不明白你是如何将可选协议功能的概念与统一访问原则联系起来的。考虑所有要计算的函数和所有要存储的属性这一简单事实本身可能违反了您正在制定的统一访问原则。重要的是,在您的示例代码中,
incrementForCount()
是一种名称不表示或不试图强制执行存储值或计算值的方法fixedIncrement
可能取决于您对这个名称稍差的属性的解释。但在这两种情况下,它们都不是协议的可选成员,我认为你的协议没有经过深思熟虑。如果我实现了这一点,并且incrementForCount()
是有意义的,那么我只需将其作为协议的唯一成员,而不是可选的@卡克尔:你想吗?
class Person {
let birthDate: NSDate
var calculateAge: Int {
NSCalendar.currentCalendar().components(NSCalendarUnit.CalendarUnitYear, fromDate: birthDate, toDate: NSDate(), options: nil).year
}
init(birthDate: NSDate) {
self.birthDate = birthDate
}
}
class Person {
let birthDate: NSDate
let getAge: Int
init(birthDate: NSDate, age: Int) {
self.birthDate = birthDate
getAge = age
}
}