Julia v0.6 конструкторы и новое ключевое слово - PullRequest
0 голосов
/ 20 мая 2018

Меня очень смущают параметрические составные типы (структуры) в Юлии.Я использую 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)

`

1 Ответ

0 голосов
/ 20 мая 2018

Я думаю, вам следует прочитать эту часть документации Джулии .

Короткие ответы на ваши вопросы:

1) Метод совершает любые вещи.Конструктор создает объект.(Это специальный метод, если хотите)

2) Он используется для создания объекта в определении типа.

3) Используйте new{T}(55,y) вместо new(55,y).

Первый случай

Ваш Point{G}(x,y) where {G<:Integer} = new(55,y) в первом случае - это внутренний конструктор .Внутренний, потому что он живет внутри определения типа.Конструкторы всегда существуют, т.е. даже если вы закомментируете эти строки, вы все равно можете сделать Point{Int64}(3,2).Так что вы на самом деле делаете переопределение конструктора по умолчанию, явно сообщая Джулии, что делать для конкретного случая 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}, но Джулия достаточно умна, чтобы автоматически приниматьG от конструктора на lhs.Это будет проблемой в случае 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).Я не знаю, почему Джулия не перечисляет различные конструкторы явно.

# 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, для lhs не задан параметр типа, который Джулия могла бы использовать автоматически.

Возможно, кто-то, обладающий большими техническими знаниями о Джулии, может дать более точный ответ.Но до тех пор, я надеюсь, это поможет.

...