Swift基础 some关键字不透明结果类型

本文介绍了Swift中的some关键字,用于处理不透明结果类型。在需要返回遵守特定协议的对象,而不关心具体类型时,some可以帮助解决编译器的不确定性。通过示例展示了如何使用some关键字来接收并调用遵循协议的对象的方法,无论对象是人类、动物还是机器人。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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的关键字作用,用在当返回值为不确定类型的情况。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值