swift - 协议(protocol)扩展中的方法永远不会被调用,加上书中的错误

标签 swift protocols

在《Swift ApprenticeBeginning programming with Swift 2.2》一书的第261~262页有一段关于协议(protocol)扩展的示例代码,如下所示

gamesPlayed在协议(protocol)TeamRecord、协议(protocol)扩展和结构BaseballRecord中定义

    protocol TeamRecord {
        var wins: Int { get }
        var losses: Int { get }
        var gamesPlayed: Int { get }
    }

    extension TeamRecord {
        // gamesPlay#1
        var gamesPlayed: Int {
            return (wins + losses)
        }
    }

    struct BaseballRecord: TeamRecord{
        var wins: Int
        var losses: Int
        // gamesPlay#2
        let gamesPlayed: Int = 162
    }

    let team1: TeamRecord = BaseballRecord(wins: 10, losses: 5)
    let team2: BaseballRecord = BaseballRecord(wins: 10, losses: 5)

    team1.gamesPlayed//The book claimed it will invoke "gamesPlay#1" (15)
    team2.gamesPlayed//The book claimed it will invoke "gamesPlay#2" (162)

问题:根据书上的描述,team1调用的gamesPlayed调用了协议(protocol)扩展中的实现(gamesPlay#1 );而 team2 调用的 gamesPlayed 调用 BaseballRecord 结构中的实现 (gamesPlay#2)。

但 Xcode 7.3 Playground 告诉我一个不同的故事,team1.gamesPlayedteam2.gamesPlayed 都调用结构中的实现而不是协议(protocol)扩展。

enter image description here

问题 本书这部分的草率写法可能会误导我!如果不是,请纠正我。 (这里的图是从书中截取的)

非常感谢您的帮助和时间

额外人员:亲爱的 friend 们。如果你发现了这个问题并且也被同样的问题困扰,这里是我在向好心的帮助者学习后编写的简单的独立代码。只需将其复制并粘贴到您的 Xcode playground 中即可。希望这会对您有所帮助。

protocol MyProtocol {
    func hardCasting()
}

extension MyProtocol {
    func foo() {
    print("Printing from the protocol extension")
    }

    func fooDefaul() {
    print("Not implemented in type, I'm  prented from the protocol extension")
    }

    func hardCasting() {
    print("You shouldn't see this!!! YOU SHALL NOT PASS!")
    }
}

struct MyType: MyProtocol {
    func foo() {
    print("Printing from the type")
    }

    func hardCasting() {
    print("No matter what! I get only printed out by type!")
    }
}

let lumi: MyProtocol = MyType()

lumi.foo()
lumi.fooDefaul()

let lumiProtocol: MyProtocol = MyType()
let lumiType: MyType = MyType()

lumiProtocol.hardCasting()
lumiType.hardCasting()

最佳答案

你是对的,这是书上的错误。如果方法是在协议(protocol)定义本身中声明的,则总是在协议(protocol)扩展之前选择具体实现。

但是,如果该方法是由协议(protocol)扩展添加的,没有在协议(protocol)定义中声明,并且也是在具体类型中实现的,您可以得到扩展的通过将具体类型转换为协议(protocol)来实现。

换句话说,如果示例代码包含以下内容:

protocol TeamRecord {
    var wins: Int { get }
    var losses: Int { get }
}

而不是这个:

protocol TeamRecord {
    var wins: Int { get }
    var losses: Int { get }
    var gamesPlayed: Int { get }
}

那么书中的评论就是正确的。

这里有一个非常彻底的探索:

https://nomothetis.svbtle.com/the-ghost-of-swift-bugs-future

关于swift - 协议(protocol)扩展中的方法永远不会被调用,加上书中的错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37711016/

相关文章:

swift - 符合具有通用约束的协议(protocol)的弱属性

ios - 根据元组的第二个值对数组进行排序

ios - ScrollView : unexpectedly found nil while unwrapping an Optional value

java - 不支持 Steammobile 协议(protocol)

objective-c - 一些协议(protocol)问题

xcode - 委托(delegate)协议(protocol)不起作用,返回 nil

c - 两个软件实体(Uart/I2C/等)之间串行通信的简单实现

swift - 更改屏幕尺寸时 Sprite 从场景中消失

xcode - 错误 'Unsupported Configuration' 是什么意思?

swift - fatal error : unexpectedly found nil