Crystal: 如何在child中用一个方法实现多个抽象方法?
Crystal: how to implement multiple abstract methods with one method in child?
假设我有一个抽象结构需要像这样对两种输入进行操作(有关更多上下文,请参阅 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
,它既不符合摘要 class 的 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
这是一个非常简单的解决方案,但可能不如将两种方法分开那么干净。 play 您只需要将抽象方法更改为一个元组,而不是两个单独的方法。
我能想到的最好的方法是在抽象中定义连接方法 class,有点类似于 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
它的工作方式是,如果它们由您单独定义,那么组合方法会出现以确保类型安全,但不会使用。如果你一起定义它们,你覆盖了第三个方法,但其他两个不会给你带来麻烦,因为满足第三个条件的程序满足前两个。
假设我有一个抽象结构需要像这样对两种输入进行操作(有关更多上下文,请参阅 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
,它既不符合摘要 class 的 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
这是一个非常简单的解决方案,但可能不如将两种方法分开那么干净。 play 您只需要将抽象方法更改为一个元组,而不是两个单独的方法。
我能想到的最好的方法是在抽象中定义连接方法 class,有点类似于 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
它的工作方式是,如果它们由您单独定义,那么组合方法会出现以确保类型安全,但不会使用。如果你一起定义它们,你覆盖了第三个方法,但其他两个不会给你带来麻烦,因为满足第三个条件的程序满足前两个。