【问题标题】:Variable that conforms to a protocol that has a generic function符合具有通用功能的协议的变量
【发布时间】:2017-05-06 03:16:03
【问题描述】:

我有一个如下所示的协议:

protocol MyProtocol {
   associatedtype SpeedType
   var name: String {get set}
   func forward(_: SpeedType)
}

我制作了 2 个符合此协议的简单类:

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() 方法设为“通用”之前,我能够做到这一点,但是现在我遇到了下一个错误: 协议“MyProtocol”只能用作通用约束,因为它具有 Self 或关联类型要求。

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

【问题讨论】:

标签: swift generics protocols


【解决方案1】:

Swift 不允许这样做。

原因如下:您对person.forward(_:) 采用的参数类型一无所知。没有办法调用它。 MyProtocol 本质上定义了一组开放式独立类型。

如果您不想调用person.forward(_:),而只想访问非泛型person.name 属性,则将您的协议拆分为定义@ 的基本非泛型协议987654325@,以及添加通用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(_:) 方法?
  • 没有。我已经在答案的第二段中回答了这个问题。我不知道该怎么说清楚了。
猜你喜欢
  • 2019-11-23
  • 2016-12-05
  • 1970-01-01
  • 2023-03-18
  • 1970-01-01
  • 2018-06-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多