实现接受并返回Self的协议静态方法(在swift中)

实现接受并返回Self的协议静态方法(在swift中),swift,generics,swift-protocols,Swift,Generics,Swift Protocols,给出一个协议,大致如下: protocol Thing { static func *(lhs: Float, rhs: Self) -> Self } 如何实现box类 class ThingBox<T: Thing>: Thing { var thing: T required init(thing: T) { self.thing = thing } static func *(lhs: Float, rhs: Self) -> Self {

给出一个协议,大致如下:

protocol Thing {
  static func *(lhs: Float, rhs: Self) -> Self
}
如何实现box类

class ThingBox<T: Thing>: Thing {
  var thing: T
  required init(thing: T) { self.thing = thing }
  static func *(lhs: Float, rhs: Self) -> Self {
    return Self(thing: lhs * rhs.thing)
  }
}
class ThingBox:Thing{
变量:T
必需的init(thing:T){self.thing=thing}
静态函数*(左:浮动,右:自)->自{
返回自我(对象:lhs*rhs.对象)
}
}
编译器抱怨在方法类型中不能使用
Self
,但是
ThingBox
是子类的这一事实意味着使用
ThingBox
是不合适的


如果不强制将该类设置为
final
,是否不可能编写该类?

您的
*
实现存在一些微妙的问题。以下是您的意思:

static func *(lhs: Float, rhs: ThingBox<T>) -> Self {
    return self.init(thing: lhs * rhs.thing)
}
意思是
Animal.f
将接受
Animal
,但
Dog.f
将只接受
Dog
,而不会接受
Cat
。因此,你会认为以下是正确的:

dog.f(otherDog) // this works
dog.f(cat) // this fails
但这违反了替代规则。如果我写下这样的话:

let animal: Animal = Dog()
animal.f(cat)
这应该是合法的,因为
Animal.f
可以接受任何
Animal
,但是
Dog.f
的实现不能接受猫。类型不匹配。繁荣所以这是不合法的。(对于返回类型不存在此限制。我将把它留给读者作为练习。尝试创建一个类似上面的示例,用于返回
Self

第二个错误只是语法错误。它不是
Self()
,而是
Self.init()
。在静态方法中,
self
是动态类型(这是您想要的),Swift要求您以这种方式显式调用
init
。这只是语法问题,而不是像另一个那样的深层类型问题


斯威夫特没有办法继承你说的东西。如果要重载,这很好,但必须明确说明类型:

class OtherBox: ThingBox<Int> {
    static func *(lhs: Float, rhs: OtherBox) -> Self {
        return self.init(thing: lhs * rhs.thing)
    }
}
class-OtherBox:ThingBox{
静态函数*(左:浮动,右:其他框)->Self{
返回self.init(thing:lhs*rhs.thing)
}
}
这正是你想要的,但它必须添加到每个孩子;它不会自动继承协方差。斯威夫特没有一个强大的协方差系统来表达它


这就是说,当你开始以这种方式混合使用泛型、协议和子类时,你会遇到很多奇怪的情况,既有数学上的原因,也有当前Swift的局限性。您应该仔细询问您的实际代码是否需要如此多的参数化。我遇到的这类问题的大多数情况都是过度设计的“以备不时之需”,而仅仅简化您的类型并使事情具体化就是解决您想要编写的实际程序所需要的一切。并不是说在更高级的类型上构建难以置信的通用算法不好,而是Swift现在已经不是这种语言了(而且可能永远不会;添加这些特性会有很多成本)。

但是这会导致所有调用
*
的结果类型都是
ThingBox
。如果我使用
*
乘以
ThingBox
的子类(比如
类OtherBox:ThingBox{…}
),结果是
ThingBox
而不是
OtherBox
,这似乎与协议中指定的类型相矛盾。
class OtherBox: ThingBox<Int> {
    static func *(lhs: Float, rhs: OtherBox) -> Self {
        return self.init(thing: lhs * rhs.thing)
    }
}