2014-10-30 35 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