Swift 由于引用协议中无效的关联类型而导致的神秘错误

Swift 由于引用协议中无效的关联类型而导致的神秘错误,swift,protocols,associated-types,Swift,Protocols,Associated Types,在线Swift 5.1编译器编译以下代码并报告错误。最重要的一点如下: main.swift:18:23: error: reference to invalid associated type 'Other' of type 'Sparrow' func sing(with f: Other) { ^ Stackoverflow上的另一个线程在一个更复杂的案例中提出了同样的问题。(). 这个问题还没有答案 我的案例代码和编译器报告错误的完整列表如下所示:

在线Swift 5.1编译器编译以下代码并报告错误。最重要的一点如下:

main.swift:18:23: error: reference to invalid associated type 'Other' of type 'Sparrow'
func sing(with f: Other) {
                  ^
Stackoverflow上的另一个线程在一个更复杂的案例中提出了同样的问题。(). 这个问题还没有答案

我的案例代码和编译器报告错误的完整列表如下所示:

    protocol Flier {
    associatedtype Other

    func flockTogether(with f:Other)
    func sing(with f:Other)
}

struct Sparrow : Flier {
    let name: String

    init (_ name: String) {
        self.name = name
    }

    func flockTogether(with f: Other) {
        print("Birds, \(name), and \(f.name), of a feather flock together.")
    }
    func sing(with f: Other) {
        sing()
        f.sing()
    }
    func sing () {
        print("Sparrow sings \"chirp, chirp\"!")
    }
}

struct Parrot {
    let name: String

    init (_ name: String) {
        self.name = name
    }

    func sing () {
        print("Parrot sings \"chuck, chuck\"!")
    }
}
struct Canary: Flier {
    let name: String
        
    init (_ name: String) {
        self.name = name
    }
    func flockTogether(with f: Other) {}
    func sing(with f: Other) {}

    func sing () {
        print("Canary sings \"tweet, tweet\"!")
    }
}
let sparrow = Sparrow("sparrow")
let parrot = Parrot("parrot")
let canary = Canary("canary")
sparrow.flockTogether(with: parrot)
sparrow.sing(with: parrot)
sparrow.flockTogether(with: canary)
sparrow.sing(with: canary)
编译器报告的错误:

main.swift:18:23: error: reference to invalid associated type 'Other' of type 'Sparrow'
    func sing(with f: Other) {
                      ^
main.swift:8:8: error: type 'Sparrow' does not conform to protocol 'Flier'
struct Sparrow : Flier {
       ^
main.swift:2:20: note: protocol requires nested type 'Other'; do you want to add it?
    associatedtype Other
                   ^
main.swift:38:8: error: type 'Canary' does not conform to protocol 'Flier'
struct Canary: Flier {
       ^
main.swift:2:20: note: protocol requires nested type 'Other'; do you want to add it?
    associatedtype Other
                   ^
compiler exit status 1

请帮我找出上面代码中的错误。多谢各位

这段代码有很多错误

  • 麻雀
    金丝雀
    被宣布符合
    飞行物
    ,但没有说明它们各自的
    其他
    类型

  • 您正试图将
    鹦鹉
    金丝雀
    传递给
    sparrow.flockTogether(与:)
    sparrow.sing(与:)
    ,但这些方法只接受一种对象-
    sparrow.Other
    。这一点以及上面的观点表明,您可能误解了关联的类型是什么。我建议你

  • 您正在尝试访问不一定存在的内容,例如
    f.name
    f.sing()
    。回想一下,
    f
    是一个
    Other
    ,它不受任何类型的限制,因此它可以是任何类型。“任何东西”都不会总是有一个
    名称供您访问

  • 我建议以下几点来帮助打电话的人工作:

  • 删除关联的类型并改用泛型方法。如果调用方决定是否传入
    鹦鹉
    金丝雀
    ,则关联类型不合适

  • name
    sing()。如果我们随后将
    Other
    (上述泛型方法的泛型参数)约束到
    Flier
    ,那么我们可以访问
    sing()
    name
    ,而不会出现任何问题

  • 也要使鹦鹉符合传单

  • 修复代码现在看起来像:

    protocol Flier {
        var name: String { get }
        func flockTogether<Other: Flier>(with f:Other)
        func sing<Other: Flier>(with f:Other)
        func sing()
    }
    
    struct Sparrow : Flier {
        let name: String
    
        init (_ name: String) {
            self.name = name
        }
    
        func flockTogether<Other: Flier>(with f:Other) {
            print("Birds, \(name), and \(f.name), of a feather flock together.")
        }
        func sing<Other: Flier>(with f:Other) {
            sing()
            f.sing()
        }
        func sing () {
            print("Sparrow sings \"chirp, chirp\"!")
        }
    }
    
    struct Parrot : Flier{
        func flockTogether<Other>(with f: Other) where Other : Flier { }
        
        func sing<Other>(with f: Other) where Other : Flier { }
        
        let name: String
    
        init (_ name: String) {
            self.name = name
        }
    
        func sing () {
            print("Parrot sings \"chuck, chuck\"!")
        }
    }
    struct Canary: Flier {
        let name: String
    
        init (_ name: String) {
            self.name = name
        }
        func flockTogether<Other: Flier>(with f:Other) {}
        func sing<Other: Flier>(with f:Other) {}
    
        func sing () {
            print("Canary sings \"tweet, tweet\"!")
        }
    }
    
    协议传单{
    变量名称:字符串{get}
    func(连同f:其他)
    func sing(附f:其他)
    func sing()
    }
    结构麻雀{
    let name:String
    init(u名称:String){
    self.name=名称
    }
    func(连同f:其他){
    打印(“鸟,\(名字)和\(名字),羽毛群在一起。”)
    }
    func sing(附f:其他){
    sing()
    f、 sing()
    }
    奉承(){
    打印(“麻雀唱“唧唧,唧唧”!”)
    }
    }
    结构鹦鹉:传单{
    func聚集在一起(与f:Other一起),其中Other:Flier{}
    func-sing(带f:Other)where-Other:Flier{}
    let name:String
    init(u名称:String){
    self.name=名称
    }
    奉承(){
    打印(“鹦鹉唱“查克,查克”!”)
    }
    }
    结构金丝雀:传单{
    let name:String
    init(u名称:String){
    self.name=名称
    }
    func(与f:Other一起){}
    func sing(带f:Other){}
    奉承(){
    打印(“金丝雀唱\“推特,推特\”!”)
    }
    }
    
    此代码有很多错误

  • 麻雀
    金丝雀
    被宣布符合
    飞行物
    ,但没有说明它们各自的
    其他
    类型

  • 您正试图将
    鹦鹉
    金丝雀
    传递给
    sparrow.flockTogether(与:)
    sparrow.sing(与:)
    ,但这些方法只接受一种对象-
    sparrow.Other
    。这一点以及上面的观点表明,您可能误解了关联的类型是什么。我建议你

  • 您正在尝试访问不一定存在的内容,例如
    f.name
    f.sing()
    。回想一下,
    f
    是一个
    Other
    ,它不受任何类型的限制,因此它可以是任何类型。“任何东西”都不会总是有一个
    名称供您访问

  • 我建议以下几点来帮助打电话的人工作:

  • 删除关联的类型并改用泛型方法。如果调用方决定是否传入
    鹦鹉
    金丝雀
    ,则关联类型不合适

  • name
    sing()。如果我们随后将
    Other
    (上述泛型方法的泛型参数)约束到
    Flier
    ,那么我们可以访问
    sing()
    name
    ,而不会出现任何问题

  • 也要使鹦鹉符合传单

  • 修复代码现在看起来像:

    protocol Flier {
        var name: String { get }
        func flockTogether<Other: Flier>(with f:Other)
        func sing<Other: Flier>(with f:Other)
        func sing()
    }
    
    struct Sparrow : Flier {
        let name: String
    
        init (_ name: String) {
            self.name = name
        }
    
        func flockTogether<Other: Flier>(with f:Other) {
            print("Birds, \(name), and \(f.name), of a feather flock together.")
        }
        func sing<Other: Flier>(with f:Other) {
            sing()
            f.sing()
        }
        func sing () {
            print("Sparrow sings \"chirp, chirp\"!")
        }
    }
    
    struct Parrot : Flier{
        func flockTogether<Other>(with f: Other) where Other : Flier { }
        
        func sing<Other>(with f: Other) where Other : Flier { }
        
        let name: String
    
        init (_ name: String) {
            self.name = name
        }
    
        func sing () {
            print("Parrot sings \"chuck, chuck\"!")
        }
    }
    struct Canary: Flier {
        let name: String
    
        init (_ name: String) {
            self.name = name
        }
        func flockTogether<Other: Flier>(with f:Other) {}
        func sing<Other: Flier>(with f:Other) {}
    
        func sing () {
            print("Canary sings \"tweet, tweet\"!")
        }
    }
    
    协议传单{
    变量名称:字符串{get}
    func(连同f:其他)
    func sing(附f:其他)
    func sing()
    }
    结构麻雀{
    let name:String
    init(u名称:String){
    self.name=名称
    }
    func(连同f:其他){
    打印(“鸟,\(名字)和\(名字),羽毛群在一起。”)
    }
    func sing(附f:其他){
    sing()
    f、 sing()
    }
    奉承(){
    打印(“麻雀唱“唧唧,唧唧”!”)
    }
    }
    结构鹦鹉:传单{
    func聚集在一起(与f:Other一起),其中Other:Flier{}
    func-sing(带f:Other)where-Other:Flier{}
    let name:String
    init(u名称:String){
    self.name=名称
    }
    奉承(){
    打印(“鹦鹉唱“查克,查克”!”)
    }
    }
    结构金丝雀:传单{
    let name:String
    init(u名称:String){
    self.name=名称
    }
    func(与f:Other一起){}
    func