Crystal:如何在子级中使用一个方法实现多个抽象方法? [英] Crystal: how to implement multiple abstract methods with one method in child?

查看:87
本文介绍了Crystal:如何在子级中使用一个方法实现多个抽象方法?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我有一个抽象结构,需要像这样对两种输入进行操作(有关更多上下文,请参见先前的SO问题)。

Suppose I have an abstract struct that needs to operate on two kinds of inputs like so (for more context, see previous SO question).

abstract struct Numberlike
  alias Num = (Int32 | Float64)
  abstract def -
  abstract def -(other : self)
  abstract def -(other : Num)
end

如果我的实现可以使用 self Num 互换使用,将它们放在一起似乎是合理的:

If my implementation can use self and Num interchangeably, it seems reasonable to just put them together:

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 的要求。

The truth is though that since the type is self | Num it matches neither the self nor the Num requirement of the abstract class.

您可以在游乐场

有没有办法像我想要的那样组合这些?我宁愿不要不必要地复制代码(即以下编译,但我不喜欢它):

Is there a way to combine these like I want? I'd rather not duplicate the code unnecessarily (i.e. the following compiles but I don't like it):

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


推荐答案

最好的我能够想到的是在抽象类中定义joind方法,这与Samual所说的有点类似。如果采用这种方式,则实现结构可以自由地分别定义每个或全部组合。

The best I've been able to come up with, is to define the joined method in the abstract class, somewhat similar to what Samual is talking about. If done this way, the implementing structs are free to define each separately or all combined.

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

工作方式如果它们是由您分别定义的,则为确保类型安全,会使用组合方法,但不会使用。如果一起定义它们,则可以覆盖第三个方法,但是其他两个方法不会给您带来麻烦,因为满足第三个条件的程序可以满足前两个条件。

The way this works is that if they are defined separately by you, then the combined method comes along for type safety but isn't used. If you define them together, you override the third method, but the other two won't give you trouble because a program which satisfies the third condition satisfies the first two.

这是一个演示: https://play.crystal-lang.org/#/r/ 6y3j

这篇关于Crystal:如何在子级中使用一个方法实现多个抽象方法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆