如何通过方法在水晶中进行阻挡

问题描述 投票:0回答:2

如何将plus传递到calculate方法?

def calculate(&block : (Float64, Float64) -> Float64)
  block.call(1.1, 2.2)
end

def plus(a, b)
  a + b
end

calculate{|a, b| plus a, b}

这不起作用

calculate ->plus
calculate &plus

P.S。

另一个问题,如何使其适用于所有数字?不只是Float64。此代码不会编译,也不会抱怨需要比Number

更具体的类型
def calculate(&block : (Number, Number) -> Number)
  block.call(1, 2)
end

理想情况下,最好将其推广为typeof(block.call(1, 2)) => Int32typeof(block.call(1.1, 2.2)) => Float64

crystal-lang
2个回答
1
投票

如何将加号传递给计算方法?

您正在寻找

calculate(&->plus(Float64, Float64))

->plus(Float64, Float64)返回Proc的位置。请注意,您have指定参数的类型-请参见参考手册中的From methods部分。

如何使其适用于所有数字?

我想研究forall-请参阅参考手册中关于Free variables的部分。


0
投票

一个通用的解决方案可以使用自由变量,但是有一个陷阱,因为自由变量不能从块参数派生:

def calculate(&block : (T, T) -> T) forall T # Error: undefined constant T

这是因为块参数不能重载,因为它们可以简单地被捕获而不受类型限制。

有两种方法可以使这项工作:

  1. 您可以显式传递T的类型作为参数。这有点冗长,但是可以使用捕获的block参数。
def plus(a, b)
  a + b
end

def calculate(t : T.class, &block : (T, T) -> T) forall T
  block.call(1.1, 2.2)
end

calculate(Float64, &->plus(Float64, Float64))
  1. 您可以将捕获的块参数更改为接收Proc的普通参数:
def plus(a, b)
  a + b
end

def calculate(block : (T, T) -> T) forall T
  block.call(1.1, 2.2)
end

calculate(->plus(Float64, Float64))
© www.soinside.com 2019 - 2024. All rights reserved.