swift - 无法在 Swift 中创建符合协议(protocol)的类型数组

标签 swift protocols associated-types

我有以下协议(protocol)和一个符合它的类:

protocol Foo{
    typealias BazType

    func bar(x:BazType) ->BazType
}


class Thing: Foo {
    func bar(x: Int) -> Int {
        return x.successor()
    }
}

当我尝试创建一个 foo 数组时,我得到一个奇怪的错误:

var foos: Array<Foo> = [Thing()]

Protocol Foo can only be used as a generic constraint because it has Self or associated type requirements.

好的,所以它只能在有关联类型要求(确实如此)的情况下使用,但由于某种原因这是一个错误??什么鬼?!

我不确定我是否完全理解编译器试图告诉我的内容...

最佳答案

假设,如果我们可以将 Thing 的实例放入数组 foos 中,会发生什么?

protocol Foo {
    associatedtype BazType
    func bar(x:BazType) -> BazType
}

class Thing: Foo {
    func bar(x: Int) -> Int {
        return x.successor()
    }
}

class AnotherThing: Foo {
    func bar(x: String) -> String {
        return x
    }
}

var foos: [Foo] = [Thing()]

因为 AnotherThing 也符合 Foo,所以我们也可以把它放到 foos 中。

foos.append(AnotherThing())

现在我们从 foos 中随机获取一个 foo

let foo = foos[Int(arc4random_uniform(UInt32(foos.count - 1)))]

我要调用方法 bar,你能告诉我应该向 bar 发送一个字符串还是整数吗?

foo.bar("foo")foo.bar(1)

swift 不能。

所以只能作为泛型约束。

什么场景需要这样的协议(protocol)?

示例:

class MyClass<T: Foo> {
        let fooThing: T?

        init(fooThing: T? = nil) {
                self.fooThing = fooThing
        }
        
        func myMethod() {
                let thing = fooThing as? Thing // ok
                thing?.bar(1) // fine
                
                let anotherThing = fooThing as? AnotherThing // no problem
                anotherThing?.bar("foo") // you can do it
                
                // but you can't downcast it to types which doesn't conform to Foo
                let string = fooThing as? String // this is an error
        }
}

关于swift - 无法在 Swift 中创建符合协议(protocol)的类型数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26865779/

相关文章:

ios - Swift:如何从 firebase 检索数据?

dynamic - 如何为 Box<dyn Trait> 字段指定关联类型的值?

haskell - 关联数据族和重叠实例

ios - 子集合的 Firestore 监听器

php - 数据库中的多个条目

swift - 为什么操作符在协议(protocol) `need more context` 中?

android - Android 与 PC 通信

swift - 协议(protocol)扩展中类型约束的好处是什么?

haskell - 我们如何在保持类型安全的同时通用地处理关联类型

ios - 如何检查元素是否可点击