Crystal:如何要求实现类仅操作自身而非所有抽象类型兄弟类
解决Crystal中抽象结构体
self类型约束的问题 看起来你遇到的核心问题是Crystal中抽象方法里的self指代的是抽象类型本身,而非子类的自身类型,所以编译器会要求你的Term结构体实现接受所有Numberlike子类的方法,这和你期望的「只支持自身与数值类型操作」不符。下面是具体的解决方案:
调整抽象结构体定义:使用泛型约束
我们可以把Numberlike改成泛型抽象结构体,让每个子类明确指定自己要兼容的类型为自身,这样编译器就会按照子类的实际类型来检查实现:
abstract struct Numberlike(T) alias Num = Int32 | Float64 abstract def - : T abstract def +(other : T) : T abstract def +(other : Num) : T abstract def -(other : T) : T abstract def -(other : Num) : T abstract def *(other : T) : T abstract def *(other : Num) : T abstract def /(other : T) : T abstract def /(other : Num) : T end
实现子类Term
让Term继承这个泛型抽象结构体,并将自身作为类型参数传入,这样所有抽象方法的参数类型就会被约束为Term,完全符合你的需求:
struct Term < Numberlike(Term) alias Num = Int32 | Float64 getter coeff : Num getter sym : Symbol def initialize(@coeff, @sym); end # 实现取反操作 def - : Term Term.new(-coeff, sym) end # Term与Term相加(需保证符号一致) def +(other : Term) : Term raise ArgumentError.new("Symbols must match for addition") unless sym == other.sym Term.new(coeff + other.coeff, sym) end # Term与数值相加 def +(other : Num) : Term Term.new(coeff + other, sym) end # Term与Term相减(需保证符号一致) def -(other : Term) : Term raise ArgumentError.new("Symbols must match for subtraction") unless sym == other.sym Term.new(coeff - other.coeff, sym) end # Term与数值相减 def -(other : Num) : Term Term.new(coeff - other, sym) end # Term与Term相乘(示例逻辑:系数相乘,符号拼接) def *(other : Term) : Term Term.new(coeff * other.coeff, :"#{sym}_#{other.sym}") end # Term与数值相乘 def *(other : Num) : Term Term.new(coeff * other, sym) end # Term与Term相除(需保证符号一致) def /(other : Term) : Term raise ArgumentError.new("Symbols must match for division") unless sym == other.sym Term.new(coeff / other.coeff, sym) end # Term与数值相除 def /(other : Num) : Term Term.new(coeff / other, sym) end end
为什么这样能解决问题?
在泛型抽象结构体Numberlike(T)中,T是一个类型占位符。当Term继承Numberlike(Term)时,所有抽象方法里的T都会被替换成Term,编译器就会要求Term实现的是「接受Term类型参数」的方法,而非所有Numberlike子类,完美匹配你想要的行为。
内容的提问来源于stack exchange,提问作者KCE
相关产品推荐
相关产品推荐

