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

查看:16
本文介绍了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

如果我的实现可以交替使用 selfNum,那么将它们放在一起似乎是合理的:

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

推荐答案

我能想到的最好的方法是在抽象类中定义连接方法,有点类似于 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天全站免登陆