檢查我已經問一個相關的問題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?'調用的限制,並保持爲聯合。 –