You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Swift中为何允许将子类实例赋值给父类约束的泛型类型?

protocol Shape {}

class Rect: Shape {}

class Square: Rect {}

struct Box<T: Shape> {
    let shape: T
}

let box1 = Box(shape: Square())
let box2: Box<Rect> = box1
// Error: Cannot assign value of type 'Box<Square>' to type 'Box<Rect>'

let box3: Box<Rect> = Box(shape: Square())
// 这段代码可以正常编译
问题原因解析

核心差异在于类型推断的时机和上下文约束的作用:

  • 关于box1赋值给box2报错:
    初始化box1时,Swift会根据传入的Square()自动推断泛型参数T为Square,因此box1的类型被固定为Box<Square>。由于Swift泛型默认是不变的,Box<Square>和Box<Rect>是完全独立的类型,不存在继承或转换关系,自然无法直接赋值。

  • 关于box3编译通过:
    当直接把Box(shape: Square())赋值给明确标注为Box<Rect>的变量时,Swift会以目标类型为依据,将泛型参数T推断为Rect。此时传入的Square()作为Rect的子类实例,可以隐式向上转换为Rect类型,完全符合Box<Rect>的初始化要求,因此编译合法。

总结来说:前者是先确定了Box<Square>类型后再尝试跨泛型类型赋值(不被允许);后者是直接根据目标类型创建Box<Rect>,利用子类转父类的兼容性完成初始化。

内容的提问来源于stack exchange,提问作者Andy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 22:46:01