Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Swift 快速统一存取原则_Swift - Fatal编程技术网

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
是一个函数,必须以不同的方式访问(作为“可选”实现方法),对吗?

我认为这个问题误解了关于统一访问原则的文章,我甚至不确定协议如何适合这里的讨论

这篇文章不一定特别清楚,但有两个关键点:

  • 这句话:

    无论这种语言做什么,重要的是程序员不要违反这个原则。您经常会看到破坏统一访问的约定。这方面的一个例子可能是,数据访问器名为getAge,而计算访问器名为calage。在这两种情况下,我都强调以相同的方式命名访问者

  • 这张图:

  • 对于这个例子,我有一个类,
    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
        }
    }