swift是否支持uniform access principle?据我所知,以下code表明它不是:
@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
是一个函数,必须以不同方式访问(作为"可选"实现的方法),对吗?
答案 0 :(得分:0)
我认为这个问题误解了关于统一访问原则的文章,我甚至不确定协议如何适合这里的讨论。
文章未必特别清楚,但有两个关键:
这句话:
无论语言是什么,重要的是程序员不要违反原则。通常,您会看到破坏统一访问的约定。这方面的一个例子可能是数据访问器名为getAge,而计算访问器名为calcAge。在任何一种情况下,我都以同样的方式命名我的访问者。
因此,对于这个例子,我有一些类Person
,它有两个我们关心的属性 - age&的出生日期。
此类有两种可能的实现方式:
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
}
}
或者...
class Person {
let birthDate: NSDate
let age: Int
init(birthDate: NSDate, age: Int) {
self.birthDate = birthDate
self.age = age
}
}
在一个案例中,我们有一个计算年龄,在另一个案例中,我们有一个存储年龄。
但在这两种情况下,我们都以同样的方式访问它们。
如果第一种情况下的计算属性被替换为函数,那么违反统一访问原则就会发挥作用:calculateAge() -> Int
来电者不应关心年龄是根据出生日期计算还是存储财产。 Swift拥有允许开发人员编写代码而不违反统一访问原则的工具。
此外,我们在开发iOS和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
}
}
或者...
class Person {
let birthDate: NSDate
let getAge: Int
init(birthDate: NSDate, age: Int) {
self.birthDate = birthDate
getAge = age
}
}