具有部分默认值的Julia-lang构造函数

时间:2015-10-29 22:17:11

标签: julia

我是朱莉娅的新手,这是一种令人兴奋的语言。我只是遇到一些奇怪的行为,我无法在网上找到解释。感谢您的帮助。

    versioninfo()
Julia Version 0.4.0

Commit 0ff703b* (2015-10-08 06:20 UTC)
Platform Info:
  System: Darwin (x86_64-apple-darwin13.4.0)
  CPU: Intel(R) Core(TM) i5-4258U CPU @ 2.40GHz
  WORD_SIZE: 64
  BLAS: libopenblas (USE64BITINT DYNAMIC_ARCH NO_AFFINITY Haswell)
  LAPACK: libopenblas64_
  LIBM: libopenlibm
  LLVM: libLLVM-3.3

我定义了一个结构

type mytype
    x :: UInt8
    y :: UInt8
    mytype(n::UInt8) = new(n, 0)
end

该类型包含一个构造函数,该构造函数具有一个字段的默认值并为另一个字段获取输入。然后我测试它

 mytype(1)

LoadError: MethodError: `convert` has no method matching convert(::Type{mytype}, ::Int64)
This may have arisen from a call to the constructor mytype(...),
since type constructors fall back to convert methods.
Closest candidates are:
  call{T}(::Type{T}, ::Any)
  convert{T}(::Type{T}, !Matched::T)
  mytype(!Matched::UInt8)
while loading In[56], in expression starting on line 1

 in call at essentials.jl:56

错误信息非常混乱,我无法理解。我测试过,如果我为这两个参数提供默认值或者取两个输入,那么代码运行良好。

感谢。

2 个答案:

答案 0 :(得分:3)

我得到了

julia> mytype(1)
ERROR: MethodError: `convert` has no method matching convert(::Type{mytype}, ::Int64)
This may have arisen from a call to the constructor mytype(...),
since type constructors fall back to convert methods.
Closest candidates are:
  call{T}(::Type{T}, ::Any)
  convert{T}(::Type{T}, ::T)
  mytype(::UInt8)
 in call at essentials.jl:56

为了分解它,它说它试图调用构造函数,但没有匹配的构造函数。为什么没有构造函数匹配?因为没有从Int641)到UInt8定义的自动转化。

然后尝试convert Int64进入mytype,但该方法也未定义。然后它放弃了,并显示最接近它最初尝试的东西(mytype(::Int64))。

您可能希望提供其他方法来处理此问题,或者接受构造函数中的任何整数并使用convert强制它UInt8 - 如果失败,它将抛出异常:< / p>

julia> type mynewtype
           x :: UInt8
           y :: UInt8
           mynewtype(n::Integer) = new(n, 0)
       end

julia> mynewtype(5)
mynewtype(0x05,0x00)

答案 1 :(得分:0)

在原始问题中,mytype的成员y将始终为0,因为使用第二个参数0调用类型内部构造函数。 在这种情况下,构造实例的方法是:mytype(UInt8(25)),它产生mytype2(0x19,0x00)。 但是,它无法接受y的值:mytype(UInt8(5), UInt8(23))会产生错误。

在答案中,mynewtype可以通过内部构造函数处理正常的Int64,但是,它总是将y初始化为0 ... 在Julia中,内部构造函数初始化类型的成员。正确处理不同参数签名的方法是定义类型: type mytype2 x::UInt8 y::UInt8 end 和外部构造函数:mytype2(n::Integer) = mytype2(n,0)调用默认的,隐式的(和不可见的)内部构造函数mytype2(x,y) = new(x,y)

mytype2可由mytype2(1,2)验证,其中mytype2(0x01,0x02)mytype2(1)会产生mytype2(0x01,0x00)

更多信息:Julia 0.4 constructors documentation page,&#34;内部构造方法&#34; (本节末尾的安全类型定义建议)