some关键字 不透明结果类型
在某一些情况下,我们需要返回接受一个遵守了某协议的对象,该对象可以是任何类,但需要遵守某个协议即可,并不限定类的类型。这个时候就会有以下问题:
协议:
protocol ProtocaltTalk{
associatedtype words
func say(words:words)
}
该协议定义了说话,遵守该协议的可以是人类,可以是动物,可以是机器人。
遵守ProtocaltTalk协议的两个类型(简单举例):
class Person:ProtocaltTalk{
var age:Int
var name:String
init(name:String,age:Int){
self.name = name
self.age = age
}
func say(words: String) {
print("\(self.name) say : " + words)
}
}
class Robot:ProtocaltTalk{
var name:String = "Robot"
init(name:String) {
self.name = name
}
func say(words: Int) {
print("\(self.name) say : \(words)" )
}
}
从上面的案例我们可以看到,两个类实现的say方法是不同的。Person类是人类,说话是字符串类型的。Robot类是机器人,说话是由数字组成的数字。但都遵守了ProtocaltTalk协议。
简单实现以下两个类实例的可行性:(仅仅是测试可行性,能编译通过就行,不是知识点):
var xiaoMing = Person(name: "xiaoMing", age: 18)
var alphaRobot = Robot(name:"alpha")
xiaoMing.say(words: "修勾你饿了吗")
alphaRobot.say(words: 1010110)
运行结果:
xiaoMing say : 修勾你饿了吗
alpha say : 1010110
是可以运行的。
接下来,我们有一个需求,创建一个“听”的方法,我只需要接收遵循了ProtocaltTalk协议实现讲话那个对象即可。
/*定义一个听的函数,接受听到说话的那个对象,
这个对象只需要遵守了ProtocaltTalk协议就可以,
不管是人还是猫猫狗狗*/
func listen() -> ProtocaltTalk{
return Person.init(name: "xiaoHong", age: 16)
}
但这时候编译器编译不通过(错误提示为):
error: Learning.playground:42:18: error: protocol 'ProtocaltTalk' can only be used as a generic constraint because it has Self or associated type requirements
func listen() -> ProtocaltTalk{
^
翻译过来就是:
协议“ProtocaltTalk”只能用作泛型约束,因为它具有自身或关联的类型要求
也就是说,该ProtocaltTalk协议里面具有泛型,每个遵守了该协议的类,它的实现方法可能会有所不同,编译器无法确定你需要接收的是否为确切的对象类型,因此,在你没有告诉编译器你要接受的对象是人类还是机器人之前,编译器是不会为你处理的。
但实际上,我的需求是:
我管你是机器人还是人类,我只需要接收我听到的那个对象就可以。
也就是说,你告诉编译器,Anyway,不管是什么牛鬼蛇神,只要遵循了ProtocaltTalk协议的对象,都可以给我传送过来。
这个时候就用到了 some 关键字。
它将告诉编译器,噢,就是有那么一个存在,你给我找过来就可以了,其他的你不用管。
func listen() -> some ProtocaltTalk{
return Person.init(name: "xiaoHong", age: 16)
}
let whoWasTalking = listen()
print("I heard who was talking : \(type(of: whoWasTalking))")
运行结果:
I heard who was talking : Person
将代码换成机器人在讲话:
func listen() -> some ProtocaltTalk{
return Robot.init(name: "Alpha")
}
let whoWasTalking = listen()
print("I heard who was talking : \(type(of: whoWasTalking))")
运行结果:
I heard who was talking : Robot
这就是some的关键字作用,用在当返回值为不确定类型的情况。