Подробное руководство по Джулии

Методы и их аннотации в Джулии

Обзор методов и сопровождающих их аннотаций, а также их нюансов.

"источник"

введение

В последнем выпуске этих руководств мы сделали огромный обзор типов, изучив различные концепции, которые мы изучили до сих пор. Сегодня мы рассмотрим лучшего друга наших типов, методы, которые действительно работают с ними. Конечно, мы уже много раз рассматривали методы в прошлом, но мы лишь поверхностно рассмотрели различные типы методов и то, как их аннотировать для правильной работы с нашими типами.

Мы начнем с рассмотрения основных методов и их аннотаций. Вероятно, к этому моменту мы уже знакомы с тем, как написать функцию:

function myfunc(x::Int64)
    
end

Довольно просто, так как мы просто используем :: для аннотации типа ввода. Мы также можем сократить наши методы, записав их в одну строку с оператором утверждения:

myfunc(x::String) = print(x)

Если бы нам нужно было больше строк для этой функции, мы могли бы также использовать синтаксис begin/end.

myfunc(x::String) = begin
    println("hi")
end

Использование begin/end само по себе приведет к мгновенному запуску предоставленного кода, но вместо этого использование предварительного утверждения превратит цитату в функцию. Нашей переменной myfunc теперь присвоен тип Function. Это означает, что у нас есть Function с именем myfunc . У нашего Function есть Methods. В данном случае это методы myfunc(::String) и myfunc(::Int64) . Если мы попробуем показать нашу функцию, то увидим, что у нее есть эти два метода:

myfunc (generic function with 2 methods)

Мы также можем создать анонимную функцию, используя оператор логического права ->. Это действительно полезно для быстрых функций, которые в некоторых случаях могут быть предоставлены в качестве аргументов для других функций. Аргументы идут слева от оператора, а функция — справа.

thefunc = x::Int64 -> x + 5

Анонимные функции обрабатываются немного иначе, чем обычные функции, и они не заменяют друг друга. Если мы покажем анонимную функцию, мы увидим, что анонимной ее делает отсутствие назначенного имени.

#1 (generic function with 1 method)

Мы также можем предоставить аргументы для анонимной функции.

thefunc = (x::Int64, y::Int64) -> x + y

Теперь мы рассмотрели все различные типы функций, но есть еще один нюанс аннотаций, который мы, возможно, захотим осветить. Все в Джулии теперь можно аннотировать, пока вы находитесь в 1.8+. Версии до 1.8+ позволяют использовать любые аннотации, которые не являются глобальными (в том числе в рамках модуля). Есть также некоторые довольно серьезные преимущества в производительности, которые можно очень легко получить, просто выбрав правильные аннотации и поместив их в нужное место. . В следующем Function почти все аннотировано, и это, как правило, оптимально для производительности:

function mymethod()
    x::Int64 = 5
    [y for y in 1:5]::Vector{Int64}
    6::Int64
end

Если вы хотите узнать больше об аннотациях и о том, как они влияют на производительность, я сделал несколько показателей в другой статье, которую вы можете посмотреть здесь:



Аргументы-аннотации являются наиболее важными из них, которые мы уже много сделали, но внутри этих аннотаций также часто есть параметры, которые говорят немного больше о типе. Как и следовало ожидать, мы можем аннотировать параметр как тип, в котором он обычно выражается:

myfunc(vec::Vector{Int64}) = begin
end

Но что, если бы мы также разрешили нашему myfunc принимать Vector из Float64 в качестве параметра без написания другой функции? К счастью, мы можем добавить <: к нашим параметрам внутри этих аннотаций.

myfunc(vec::Vector{<:Number}) = begin
end

Теперь можно указать любой Vector с подтипом Number, который будет включать Float64 и Int64. Этот же метод также можно отнести к предоставлению Any типа Vector методу.

thisfunction(x::Vector{<:Any}) = print(x)

Таким образом, этой функции теперь могут быть предоставлены все виды различных векторов. Например, Vector{String} .

thisfunction(["heheth"])
["heheth"]

Методы и их аннотации - это хлеб с маслом Джулии. При этом их эффективное или неэффективное использование может повысить или снизить производительность и общую плавность ваших приложений. Эти нюансы, безусловно, различны, но для того, чтобы быть лучшим программистом, безусловно, полезно учитывать разные показатели производительности с помощью разных методов. В связи с этим, я надеюсь, что это было полезно. Спасибо за просмотр/чтение, хорошего дня!