检查我已经问一个相关的问题here,答案没有解决我的问题,但我有多么结晶检查类型,因为我一直运行到类似的问题,因此,如果有人可以帮助我更普遍的误解算出这个我会很棒。我已经尝试了很多能够与Ruby一起工作的东西,但绝对不适用于Crystal(我知道它们有很多不同,但我更熟悉Ruby)。型水晶
这里是一个类:
class Narray(T)
getter shape
getter values
@shape : Tuple(Int32, Int32) | Nil
def initialize(values : T)
@values = values
@type = T
@shape = set_shape
end
def set_shape
if (@type == Array(Array(Int32))) || (@type == Array(Array(Float64)))
return {values.size, values[0].size} # Line causing the error
elsif (@type == Array(Int32)) || (@type == Array(Float64))
return {1, @values.size}
end
end
def is_matrix?
if @values[0].is_a?(Array(Int32)) || @values[0].is_a?(Array(Float64))
return true
else
return false
end
end
end
要定义的阵列,我应该做的:
arr1 = Narray.new([1,2,3])
这将通过set_shape
运行来检索阵列的形状(表示的数量的元组行数和列数)。 在这种方法中,我检查if语句是否是2D数组。 然而,上面跑线的时候,我得到这个错误:
in script.cr:16: undefined method 'size' for Int32
return {values.size, values[0].size}
这正是if语句应该避免什么第一。由于我正在初始化一维数组,它不应该通过.size
部分。
我敢肯定这是一个简单的解释,并且有一些非常基本的,我没有得到,但我想获得它,而不是在这个问题上磕磕绊绊所有的时间。
我该如何检查Crystal的类型,因为我使用的方式不正确? 我使用is_a?
,== Type
,使用is_matrix?
方法(它正常工作和做决定,如果是2D或1D的工作,但仍然可以通过错部分运行)尝试。
编辑:根据第一个答案,我已经改变了set_shape
方法:
def set_shape
if (@values.is_a? Array(Array(Int32))) || (@values.is_a? Array(Array(Float64)))
return {values.size, values[0].size}
elsif (@values.is_a? Array(Int32)) || (@values.is_a? Array(Float64))
return {1, @values.size}
end
end
但我还是有相同的错误
谢谢您的回答。我已经尝试了你的建议,即直接评估@values的类型,但没有起作用(请参阅我的编辑,我已经添加了我尝试过的)。当你说有两种不同的类型时,你的意思是有两个不同的类?理想情况下,我试图创建一个类型与numpy ndarrays相同的功能,非常方便。在我看来,为什么它很方便的一部分是因为它是1D/2D/Int/Float的一种类型。但我总是对建议开放,如果你对这个类有任何“设计”建议,它会很棒 –
问题在于你一直提到'@ values'并且不提前制作它的本地副本'values = @ values'。该类型将被正确限制为一个局部变量,因为它的类型不会改变(它是本地的函数),但实例变量可能随时被另一个线程或另一个函数改变(它是一个共享值),所以它的类型类型不会受到'is_a?'调用的限制,并保持为联合。 –