swift - 符合具有通用功能的协议(protocol)的变量

标签 swift generics protocols

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

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

我制作了两个符合此协议(protocol)的简单类:

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

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

最佳答案

Swift 不允许这样做。

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

如果您不想调用 person.forward(_:),而只想访问非泛型 person.name code> 属性,然后将协议(protocol)拆分为定义 name 的基本非通用协议(protocol),以及添加通用 forward(_:) 方法的子协议(protocol)。

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")
}

关于swift - 符合具有通用功能的协议(protocol)的变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43816356/

相关文章:

ios - Xcode 7 中没有类型或协议(protocol)命名错误如何解决?

xmpp - 适合即时通讯的协议(protocol)

objective-c - 继承的属性不起作用

ios - 包含本地 Cocoapod 框架作为依赖项

ios - '传递给不带参数的调用的参数'实例化 HKWorkoutRouteQuery

ios - 从本地路径播放视频

c# - 如何通过以下语法访问 C# 字典元素?

ios - 在 Xcode7 beta 中集成解析

java - 如何从通用静态工厂方法返回参数化派生类

java - Spring 3.1 Autowiring 具有多个泛型参数的泛型类