有一种方法-做某事-一种。使用协议,有一种方法可以消除类型限制,并且仍然可以得到所需的结果,但这并不总是很漂亮。这是我根据您的情况提出的协议:
protocol MyProtocol { func getValue() -> Self }extension Int: MyProtocol { func getValue() -> Int { return self }}extension Double: MyProtocol { func getValue() -> Double { return self }}
请注意,
value您最初放在协议声明中的属性已更改为返回对象的方法。
那不是很有趣。
但是现在,由于您已经摆脱
value了协议中的属性,因此
MyProtocol可以将其用作类型,而不仅仅是类型约束。您的
Container班级甚至都不再需要泛型。您可以这样声明:
class Container { var values: [MyProtocol] init(_ values: MyProtocol...) { self.values = values } func myMethod() -> [MyProtocol] { return values }}
而且由于
Container不再通用,因此您可以创建一个
Array,
Container然后遍历它们,打印
myMethod()方法的结果:
var containers = [Container]()containers.append(Container(1, 4, 6, 2, 6))containers.append(Container(1.2, 3.5))for container in containers { println(container.myMethod())}// Output: [1, 4, 6, 2, 6]// [1.2, 3.5]
诀窍是构造 仅包含通用功能且对符合类型没有其他要求 的协议 。 如果您可以避免这样做,那么可以将协议用作类型,而不仅仅是类型约束。
另外(如果您想这样称呼),您的
MyProtocol值数组甚至可以混合符合的不同类型
MyProtocol。因此,如果您给出这样
String的
MyProtocol扩展名:
extension String: MyProtocol { func getValue() -> String { return self }}
您实际上可以
Container使用混合类型初始化a :
let container = Container(1, 4.2, "no kidding, this works")
[警告-我正在一个在线游乐场进行测试。我还不能在Xpre中对其进行测试…]
编辑:
如果你仍然想
Container成为通用的,只能容纳一个类型的对象,就可以完成,通过使 之 符合自己的协议:
protocol ContainerProtocol { func myMethod() -> [MyProtocol]}class Container<T: MyProtocol>: ContainerProtocol { var values: [T] = [] init(_ values: T...) { self.values = values } func myMethod() -> [MyProtocol] { return values.map { 仍然 as MyProtocol } }}
现在,您
[ContainerProtocol]可以拥有一个
myMethod()对象数组,并通过调用它们进行迭代
let containers: [ContainerProtocol] = [Container(5, 3, 7), Container(1.2, 4,5)]for container in containers { println(container.myMethod())}:
Container
也许这仍然对您不起作用,但是现在
ContainterProtocol仅限于一种类型,但是您仍然可以遍历对象数组。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)