2016-12-22 64 views
2

我已經定義了一個Container類。在@values屬性中,我需要存儲一個數組或二維數組,而這些數組中的元素可以是Int32或Float64。如果我初始化這樣的:使類型Array(T)的類成員屬性接受T的二維數組

class Container 

    def initialize(value) 
    @values = values 
    end 

end 

我得到一個錯誤:@values : Type, is inferred from assignments to it across the whole program.

如果我定義它是這樣的:

class Container 

    def initialize(value : Array) 
    @values = values 
    end 

end 

我得到:can't use Array(T) as the type of instance variable @values of Container(T), use a more specific type

我怎樣才能讓這個類更靈活,所以我可以這樣做:

Container.new([1,2,3]) 
Container.new([1.0, 3.0, 4.0]) 
Container.new([[1, 2], [4,3,2],[1]]) 
Container.new([[1.0, 4.5], [2.2, 0.0]]) 
+0

什麼是用例的集裝箱?你可以用它做什麼? – asterite

+0

目標是能夠使用它作爲numpy的ndarray,如果它是方形的,可以對它應用一些矩陣運算,如果形狀允許它們在ndarrays之間運行,並用每個元素的類型和形狀定義它的陣列。問題在於元素的類型。正如我上面寫的,我無法找到如何使它適用於一維和二維數組,以及32Int和64Float –

回答

2

做了一些挖掘之後,似乎確實有一個official way of doing this。但是,一定要規劃好,因爲使用語法構造給了我下面的水晶0.20.1

def initialize(value : Array(Array | Int32 | Float64)) 
    @values = value 
end 

Error in line 3: can't use Array(T) in unions yet, use a more specific type 

如果我正確地從您的樣本數據的理解,好像類型將是均勻(即陣列將始終包含一個特定的類型)。如果是這種情況,你可以簡單地重載構造函數。這不是一個漂亮的解決方案,但也許它可以把你綁定。

class Container 

    def initialize(value : Array(Array)) 
    @values = value 
    calculate 
    end 

    def initialize(value : Array(Int32)) 
    @values = value 
    calculate 
    end 

    def initialize(value : Array(Array(Int32))) 
    @values = value 
    calculate 
    end 

    def initialize(value : Array(Array(Float64))) 
    @values = value 
    calculate 
    end 

    def initialize(value : Array(Float64)) 
    @values = value 
    calculate 
    end 

    def calculate 
    # do stuff here 
    end 

end 

Container.new([1,2,3]) 
Container.new([1.0, 3.0, 4.0]) 
Container.new([[1, 2], [4,3,2],[1]]) 
Container.new([[1.0, 4.5], [2.2, 0.0]]) 

編輯:

看來你可以使用@ faaq的解決方案,而該類型的感謝,指定由@Sija評論。他們也共享this sample code,我認爲它比重載構造函數更清潔。

+0

你理解正確!沒有想到重載構造函數。好主意非常感謝!所以你說第一種方式應該在未來的版本中工作?這是一個更簡潔/優雅的方式。 –

+0

我相信*它會,但我不完全確定。 Crystal的gitter是一個獲得回報的好地方,當我有機會的時候我會問社區。 –

1

爲什麼不使用泛型?

class Container(Type) 

    def initialize(@values : Type) 
    pp @values 
    pp typeof(@values) 
    end 

end 

value = [1,2,3] 
Container(typeof(value)).new(value) 
value = [1.0, 3.0, 4.0] 
Container(typeof(value)).new(value) 
value = [[1, 2], [4,3,2],[1]] 
Container(typeof(value)).new(value) 
value = [[1.0, 4.5], [2.2, 0.0]] 
Container(typeof(value)).new(value) 

輸出是:

@values # => [1, 2, 3] 
typeof(@values) # => Array(Int32) 
@values # => [1.0, 3.0, 4.0] 
typeof(@values) # => Array(Float64) 
@values # => [[1, 2], [4, 3, 2], [1]] 
typeof(@values) # => Array(Array(Int32)) 
@values # => [[1.0, 4.5], [2.2, 0.0]] 
typeof(@values) # => Array(Array(Float64)) 
+1

的確,這可能有效。但是,它使得使用這個類很痛苦。編寫'Container(typeof([[1.0,4.5],[2.2,0.0]])。new([[1.0,4.5],[2.2,0.0]])'而不是'Container.new([[1.0, 4.5],[2.2,0.0]])'。使用上面的解決方案,我可以輕鬆地聲明實例並同時獲取該類型。但我同意,在課堂上這個比較短,但我現在對可用性更感興趣。通過 –

+1

提供解決方案非常感謝您不需要顯式傳遞'Type'參數,'Container.new(value)'也可以。 – Sija

相關問題