假设我有一个抽象结构,需要像这样对两种输入进行操作(有关更多上下文,请参见previous SO question)。
abstract struct Numberlike
alias Num = (Int32 | Float64)
abstract def -
abstract def -(other : self)
abstract def -(other : Num)
end
如果我的实现可以交替使用self
和Num
,则将它们放在一起似乎是合理的:
struct Term < Numberlike
alias Num = (Int32 | Float64)
getter coeff : Num
getter sym : Symbol
def initialize(@coeff, @sym); end
def -(other : self | Num)
self.class.new(coeff - other, sym)
end
def -
self.class.new(-coeff, sym)
end
end
事实是,由于类型为self | Num
,因此它既不符合抽象类的self
也不符合Num
的要求。
您可以在this playground中亲自查看。
有没有一种方法可以像我想要的那样组合这些?我不想不必要地复制代码(即以下代码,但我不喜欢):
struct Term < Numberlike
alias Num = (Int32 | Float64)
getter coeff : Num
getter sym : Symbol
def initialize(@coeff, @sym); end
def -(other : self)
self.class.new(coeff - other, sym)
end
def -(other : Num)
self.class.new(coeff - other, sym)
end
def -
self.class.new(-coeff, sym)
end
end
答案 0 :(得分:1)
这是一个非常简单的解决方案,但可能不如将两种方法分开一样干净。 play您只需要将abstract方法更改为元组而不是两个单独的方法即可。
答案 1 :(得分:0)
我能想到的最好的办法是在抽象类中定义join方法,这与Samual所说的有点类似。如果采用这种方式,则实现结构可以自由地分别定义每个或全部定义。
abstract struct Addable
abstract def +(other : self)
abstract def +(other : Int32)
def +(other : self | Int32)
if other.is_a?(Int32) ? self + other : self + other
end
end
此方法的工作方式是,如果由您分别定义它们,则可以使用组合方法来保证类型安全,但不会使用。如果一起定义它们,则可以覆盖第三个方法,但是其他两个方法不会给您带来麻烦,因为满足第三个条件的程序可以满足前两个条件。