为何Swift引用类型中返回Self无法直接返回实例,必须强制转换?
为什么Swift类中返回Self不能直接返回父类实例?
首先得搞清楚Self在类里到底代表什么——它指的是当前调用该方法的具体类型,不是写方法的那个类本身。比如你要是给Person写个子类Student:
class Student: Person {}
当你用Student的实例调用GetNewPerson2时,方法的返回类型要求是Student,但你返回的是Person实例,这俩类型根本不兼容(Person是Student的父类,父类实例不能直接当子类用),编译器肯定要报错。
那GetNewPerson1用as! Self能通过编译,是因为你强制告诉编译器“我保证这个实例就是Self类型”,但这其实非常危险——如果是子类调用这个方法,强制转换会直接崩溃,比如:
let student = Student(name: "Alice") student.GetNewPerson1() // 运行时崩溃,因为Person实例转不成Student
至于为什么协议扩展里可以直接返回实例匹配Self?这是因为协议的Self和类的Self约束逻辑不一样:
- 协议扩展里的
Self是指遵循该协议的具体类型,而且如果在扩展里返回Self实例,编译器会要求该类型必须有对应的可访问初始化器(比如协议里定义了init,或者类型本身满足初始化要求)。 - 更关键的是,协议不是类,不存在继承层级的类型不兼容问题——只要你返回的实例是遵循协议的类型,就能匹配
Self(当然如果是协议扩展里用Self(),那必须类型有默认初始化器)。
总结一下:
- 类中的
Self可能是当前类的子类,父类实例无法自动转换成子类类型,所以编译器不允许直接返回父类实例。 - 协议扩展的
Self是遵循协议的具体类型,只要返回的实例符合协议,就能匹配,不存在子类父类的类型转换问题。
内容的提问来源于stack exchange,提问作者Avii
相关产品推荐
相关产品推荐

