具有mixin的多个类的函数

时间:2017-06-08 04:47:23

标签: swift generics mixins

Mixin

我有一个打印的mixin将类名称String指定给实例变量。

import Foundation

protocol Recyclable {
    static var name: String { get }
}

extension Recyclable {
    static var name: String {
        return String(describing: Self.self)
    }
}

实现mixin有两个类:

class One: NSObject, Recyclable { }
class Two: NSObject, Recyclable { }

因此,如果我想打印类名,我可以

One.self.name // "One"

这完美无缺。现在让我们深入了解。

打印多个给定类的通用函数

将此函数放入函数中以打印所有给定类的名称。它必须是通用的,因为它可以接受任何符合Recyclable protocol的类。

func printAllNames<T: NSObject>(_ things: T.Type...) where T: Recyclable {
    for thing in things {
        print(thing.name)
    }
}

如果我只将它用于一个班级,它会按预期工作。

printAllNames(One.self) // "One"

但是当与多个一起使用时,它会出错

printAllNames(One.self, Two.self)
  

Playground执行失败:错误:GenericMixins.playground:20:1:   错误:无法推断泛型参数“T”   printAllNames(One.self,Two.self)

有关可能发生的事情的任何提示?

游乐场:https://www.dropbox.com/sh/q0b5b3oo0luj471/AABSG2QEOIj_SBsvtv7cEv-Ka?dl=0

2 个答案:

答案 0 :(得分:1)

问题,如@dirtydanee says,通用占位符T表示要在函数的调用位置处满足的类型。因此,可变参数T.Type...表示相同类型T的一系列元类型。

解决方案只是拥有一个Recyclable.Type...参数,该参数表示符合Recyclable任何类型的一系列元类型:

func printAllNames(_ things: Recyclable.Type...) {
    for thing in things {
        print(thing.name)
    }
}

printAllNames(One.self, Two.self)

这并没有表达NSObject TNSObject的约束,但您在函数本身的实现中没有使用该约束。

如果这只是一个简化的示例,并且您实际上想要为从Recyclable继承并符合NSObject & Recyclable的任何类型表达一系列元类型 - 您目前无法在Swift 3中表达这一点。

但是在Swift 4中,我们可以<{3}} func printAllNames(_ things: (NSObject & Recyclable).Type...) { for thing in things { print(thing.name) } } 来表达这一点:

request()->only('args')

答案 1 :(得分:0)

我最终搞清楚了。正确的方法是让函数接受任何东西,然后检查被接受的内容是否符合协议。

该功能应该是

printAllNames(One.self, Two.self)

然后它按预期工作

main
  

     

两个

更新了游乐场:https://www.dropbox.com/sh/9sjboo3lfu83662/AAC9CKn_dU_wrihCvKUfujQ7a?dl=0