我看到在现有的Ruby项目上设置RBS类型时出现了一些意想不到的行为。一个最小的例子:
# lib/a.rb
class A
def self.foo
new
end
end
class B < A
def self.foo
super
end
end
puts A.foo.inspect
puts B.foo.inspect
输出
#<A:0x000055f7cfb03908>
#<B:0x000055f7cfb037f0>
签名
# lib/a.rbs
class A
def self.foo: () -> A
end
class B < A
def self.foo: () -> B
end
但是陡峭的类型检查器给我错误
lib/a.rb:8:11: [error] Cannot allow method body have type `::A` because declared as type `::B`
│ ::A <: ::B
│ ::Object <: ::B
│ ::BasicObject <: ::B
│
│ Diagnostic ID: Ruby::MethodBodyTypeMismatch
│
└ def self.foo
~~~
这是一个陡峭的问题,还是(更有可能)我对Ruby类型语法的理解有问题?
1条答案
按热度按时间wxclj1h51#
这是一个陡峭的问题,还是(更有可能)我对Ruby类型语法的理解有问题?
我认为两者都不是。
你的语法非常好(否则steep甚至不能解析RBS文件,并给予你一个语法错误),我也没有看到任何问题。根据你声明的类型,你的代码是 * 真正 * 类型不安全的:
B::foo
声明为返回B
的示例B::foo
返回super
super
是A::foo
A::foo
声明为返回A
的示例*因此,
B::foo
声明为返回B
的示例,但实际上返回A
的示例。由于
A
不能转换为B
,因此这不是类型安全的。