2014-10-30 51 views
0

設置:在朱莉婭考慮一個參數類型相互作用

type MyType1{T1} 
    x::T1 
end 

我使用多個調度和類型參數定義在這種類型的單功能的兩種方法:

f1(m::MyType1, i::Int64) = m.x + i #Method 1 
f1{T1}(m::MyType1, i::T1) = m.x + i + 1 #Method 2 

方法1對應於第二輸入是Int64的情況。方法2對應於第二輸入是參數的情況。我使用m=MyType1{Int64}(1)創建了MyType1的實例,並注意m.x現在返回1

問題1:我看到以下行爲:

In : f1(m, 1.0) 

Out : 3.0 

好了,所以我沒有提供在函數調用的任何信息關於T1。看起來Julia推斷它應該執行方法2,理由是第二個輸入不是Int64。這是事實如何在引擎蓋下工作嗎?

問題2:比方說,我想調用第二種方法,但第二個輸入爲Int64。顯然f1(m, 1)將不起作用,因爲它會調用第一種方法。我嘗試這樣做:

In : f1{Int64}(m, 1) 

但朱莉婭拋出這個錯誤:

ERROR: type: instantiate_type: expected TypeConstructor, got Function 

是否有可能獲得與指定爲Int64第二輸入運行第二個方法,還是我傻?

回答

3

首先,我想知道您是否打算在第二種方法中輸入第一個參數,如m::MyType1{T1},例如,

f1{T1}(m::MyType1{T1}, i::T1) = m.x + i + 1 #Method 2b 

這意味着該第二方法只適用如果i具有相同類型爲的m類型的T1類型參數。根據您的原始定義,T1只會與實際參數i所具有的任何類型匹配,因此您不妨將其寫入f1(m::MyType1, i::Any) = ...

1)使用方法2b代替方法2,我得到

julia> f1(m, 1.0) 
ERROR: no method f1(MyType1{Int64}, Float64) 

因爲有適用都沒法。 在您的原始案例中,方法1不適用,但方法2適用。朱莉婭採用最具體的方法,例如方法2.所以是的,你可以說方法2被選中,因爲第二個輸入不是Int64

2)顯式類型參數(至少目前爲止)只支持類型而不支持函數調用。invoke函數允許調用指定的函數,並根據給定(更一般)的參數類型列表選擇方法,但我不確定是否適用於此,因爲對於MyType{Int64},這兩種方法適用於完全相同的類型第二個論點。無論哪種方式,它不建議使用invoke是一般的,我認爲它可以給一個相當大的性能損失。

如果你真的想在這種情況下能夠調用方法2,你應該找到另一種方式,你不必爭取多次派遣。一種選擇是將方法2的實施引入其自身的功能,例如,

f1(m::MyType1, i::Int64)  = m.x + i #Method 1 
f1{T1}(m::MyType1{T1}, i::T1) = g1(m, i) #Method 2b 
g1{T1}(m::MyType1{T1}, i::T1) = m.x + i + 1 

如果您想使用第二種方法,您可以直接撥打g1

順便說一句,你正在使用的任何特定原因Int64?除非你明確地需要64位,使用Int(這是typealiased要麼Int32Int64取決於你的系統)更朱利安,而且往往互操作好一點與其它代碼。

+1

你是正確的,我想實現你的方法2b。我是一個Matlab轉換器,所以仍然在學習類型方面的知識。沒有'Int64'的具體原因。如果沒有性能問題,我會很樂意切換到「Int」。同樣的規則是否適用於'Float'(即使用'Float'而不是'Float64')? ps謝謝你的答案+ 1 + Tick。非常清楚,這正是我所追求的。 – 2014-10-30 12:21:44

+2

不,你必須指定Float64或Float32。原因在於決定使用的類型很少基於機器類型,但需要精確性。 – 2014-10-30 13:08:38