符合具有通用功能的协议的变量

Ale*_*xei 2 generics protocols swift

我有一个看起来像这样的协议:

protocol MyProtocol {
   associatedtype SpeedType
   var name: String {get set}
   func forward(_: SpeedType)
}
Run Code Online (Sandbox Code Playgroud)

我做了两个符合这个协议的简单类:

class A: MyProtocol {
   typealias SpeedType = Double
   var name: String

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

   func forward(_ s: Double) {
       print("Moving \(s) km/h")
   }
}

class B: MyProtocol {
   typealias SpeedType = Int
   var name: String

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

   func forward(_ s: Int) {
       print("Moving \(s) km/h")
   }
}
Run Code Online (Sandbox Code Playgroud)

我想要实现的是能够声明一个MyProtocol类型的变量,并在以后初始化它:

let x: Bool = true
var person: MyProtocol
if x {
   person = A(name: "Robot")
} else {
   person = B(name: "Human")
}
Run Code Online (Sandbox Code Playgroud)

在我使用forward()方法"generic"之前,我能够做到这一点,但是现在我得到了下一个错误: 协议"MyProtocol"只能用作通用约束,因为它具有Self或相关类型要求.

所以我的目标是有一个方法forward(),它可以作为我指定的类型的参数参数,并且还能够声明符合我的协议的类型的变量.

rob*_*off 5

斯威夫特不允许这样做.

原因如下:你对参数的类型一无所知person.forward(_:).没有办法打电话给它.MyProtocol本质上定义了一组开放式的独立类型.

如果您不希望能够调用person.forward(_:),并且您只是希望能够访问非泛型person.name属性,那么将协议拆分为基本的非通用协议定义name,以及添加通用的子协议forward(_:)方法.

protocol NamedThing {
    var name: String {get set}
}

protocol MovableNamedThing: NamedThing {
    associatedtype SpeedType
    func forward(_: SpeedType)
}

class A: MovableNamedThing {
    typealias SpeedType = Double
    var name: String

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

    func forward(_ s: Double) {
        print("Moving \(s) km/h")
    }
}

class B: MovableNamedThing {
    typealias SpeedType = Int
    var name: String

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

    func forward(_ s: Int) {
        print("Moving \(s) km/h")
    }
}

let x: Bool = true
var person: NamedThing
if x {
    person = A(name: "Robot")
} else {
    person = B(name: "Human")
}
Run Code Online (Sandbox Code Playgroud)