ruby 如果arg是一个数组,则Sorbet不检查它的运行时类型

huus2vyu  于 2022-12-29  发布在  Ruby
关注(0)|答案(1)|浏览(100)

我有下面的代码,你可以只复制粘贴本地,并运行它作为一个单一的文件:

require 'bundler/inline'

gemfile do
  source 'https://rubygems.org'

  gem 'sorbet-runtime'
end

require 'sorbet-runtime'

class Numbers
  extend T::Sig

  sig { params(a: Integer, b: Integer).returns(Integer) }
  def sum_of_two(a, b)
    a + b
  end

  sig { params(values: T::Array[Integer]).returns(Integer) }
  def sum_of_array(values)
    values.sum
  end
end

如果我在文件末尾添加以下行,将得到以下结果

Numbers.new.sum_of_two(1, 2) # => does not fail because the actual args are ints
# Numbers.new.sum_of_two(1.0, 2) # => raises errors because one of the param is Float
Numbers.new.sum_of_array([1, 2, 3]) #=> ok, because everything matches

Numbers.new.sum_of_array([1.0, 2, 3]) #=> raises only an error when tries to match the return type

拜托,有谁能解释一下为什么它会这样?如果类型是数组,为什么它不在运行时验证类型?

n8ghc7c1

n8ghc7c11#

文档中讨论了这种确切情况:
Sorbet在运行时完全擦除 * 泛型类型参数 *。当Sorbet看到类似T::Array[Integer]的签名时,在运行时它检查参数是否具有类Array,而不是检查该数组的每个元素是否在运行时也是Integer

相关问题