我对Julia中的参数化复合类型(结构)感到困惑。我正在使用v0.6。我想知道是否有人可以向我解释这两段代码之间的区别?第一个似乎有效,但第二个给出错误(ERROR: LoadError: syntax: too few type parameters specified in "new{...}"
)。我特别困惑了:
Point{G}(x,y) where {G<:Integer} = new(55,y)
。它似乎不是一种方法?稍后请参阅println(methods(Point))
几行。它是'构造函数'吗?如果是这样,那么构造函数和方法之间的区别是什么?new
真正做了什么?`
workspace()
println("\nSTART")
struct Point{T<:Real}
x::T
y::T
# These are not 'methods' - see below. What are they!?
Point{G}(x,y) where {G<:Integer} = new(55,y)
Point{H}(x,y) where {H<:AbstractFloat} = new(x, 11)
end
println(methods(Point)) # Interesting!!!
# Are these methods? Are they 'constructors'?
Point(x::T, y::T) where {T<:Integer} = Point{T}(x,y)
Point(x::T, y::T) where {T<:AbstractFloat} = Point{T}(x,y)
println(methods(Point))
p = Point(2,3)
p2 = Point(2.0,3.0)
##########################################################################
# Errors!
workspace()
println("")
struct Point{T<:Real}
x::T
y::T
Point(x::T, y::T) where {T<:Integer} = new(55, y)
Point(x::T, y::T) where {T<:AbstractFloat} = new(x, 11)
end
println(methods(Point))
p = Point(2,3)
p2 = Point(2.0,3.0)
`
答案 0 :(得分:5)
我认为你应该阅读this part of the Julia documentation。
对您的问题的简短回答:
1)方法可以做任何事情。构造函数创建一个对象。 (如果你愿意的话,这是一种特殊的方法)
2)它用于在类型定义中创建对象。
3)使用new{T}(55,y)
代替new(55,y)
。
第一个案例
第一种情况下,Point{G}(x,y) where {G<:Integer} = new(55,y)
是内部构造函数。内在因为它存在于类型定义中。构造函数始终存在,即使您注释掉这些行,您仍然可以Point{Int64}(3,2)
。所以你实际做的是通过明确告诉Julia如何处理特定情况G<:Integer
来覆盖默认构造函数,即始终将x
设置为55
。 new(55,y)
实际上会创建一个Point{G}
对象x=55
和y=y
。 (请注意,如果您要编写Point{G}(x,y) where {G<:Integer} = Point{G}(55,y)
,我们会有一个循环,因此确实需要new()
之类的东西。)从技术上讲,您应该使用new{G}(55,y)
来创建Point{G}
对象但朱莉娅很聪明,可以自动从lhs的构造函数中获取G
。这将是案例2中的一个问题。
的输出
julia> println(methods(Point)) # Interesting!!!
# 1 method for generic function "(::Type)":
(::Type{T})(arg) where T in Base at sysimg.jl:77
告诉您,只需将类型名称(包括类型参数)作为函数名称即可调用构造函数,例如Point{Float64}(1.2, 3.4)
。我不知道为什么Julia没有明确列出不同的构造函数。
# Are these methods? Are they 'constructors'?
Point(x::T, y::T) where {T<:Integer} = Point{T}(x,y)
Point(x::T, y::T) where {T<:AbstractFloat} = Point{T}(x,y)
println(methods(Point))
这些是方法。对此的一个指示是您可以用不同的名称命名它们:create_a_point(x::T, y::T) where {T<:Integer} = Point{T}(x,y)
。你不能为(内部)构造函数执行此操作。但是,有时它们被称为“构造函数方法”。
第二种情况
您必须明确指定类型参数:new{T}(55,y)
。与案例1不同,Julia可以自动使用的lhs上没有给出类型参数。
也许对Julia有更多技术知识的人可以提供更准确的答案。但在那之前,我希望这会有所帮助。