Swift 符合具有泛型函数的协议的变量

Swift 符合具有泛型函数的协议的变量,swift,generics,protocols,Swift,Generics,Protocols,我有这样一个协议: protocol MyProtocol { associatedtype SpeedType var name: String {get set} func forward(_: SpeedType) } 我创建了两个符合此协议的简单类: class A: MyProtocol { typealias SpeedType = Double var name: String init(name:String) { self.

我有这样一个协议:

protocol MyProtocol {
   associatedtype SpeedType
   var name: String {get set}
   func forward(_: SpeedType)
}
我创建了两个符合此协议的简单类:

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")
   }
}
我想要实现的是能够声明MyProtocol类型的变量,并在以后像这样初始化它:

let x: Bool = true
var person: MyProtocol
if x {
   person = A(name: "Robot")
} else {
   person = B(name: "Human")
}
在我使用forward()方法“generic”之前,我能够做到这一点,但是现在我遇到了下一个错误: 协议“MyProtocol”只能用作泛型约束,因为它具有自身或关联的类型要求。


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

Swift不允许这样做

原因如下:您对参数的类型一无所知。没有办法叫它
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")
}

可能是重复的感谢,这是有效的。有趣的解决方案,我甚至都没想过。有什么方法可以调用person变量的forward(:)方法吗?没有。我已经在回答的第二段中回答了这个问题。我不知道怎么说得更清楚了。