Расширенный взгляд на ввод функции в Julia.

введение

На первый взгляд разработка программного обеспечения и программирование кажутся очень сложными. Восприятие программного обеспечения в поп-культуре и в обществе в целом таково, что оно требует абсурдного количества интенсивной математики и часто очень сложно. Хотя алгоритмы, безусловно, могут усложняться, было бы полезно взглянуть на программирование через гораздо более упрощенную призму; таким образом, мы могли бы сделать цель более доступной. Программирование в его простейшей форме всегда будет связано с вводом и выводом. В конечном счете, компьютер предназначен для того, чтобы принимать какие-то входные данные и производить выходные данные. Во многих случаях это могут быть периферийные устройства — вы нажимаете клавишу K на клавиатуре, и это обеспечивает вывод добавления символа к тому, что вы печатаете. Настоящей проблемой программирования является все, что находится между этими входными и выходными данными, код, который принимает входные данные и возвращает заданный результат.

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

аргументы

В Джулии есть два основных типа аргументов; позиционный аргумент и аргумент ключевого слова. Позиционные аргументы являются типичными аргументами, и то, как они используются, указано в названии. Давайте рассмотрим базовый позиционный аргумент:

function example(x::Integer)

end

В приведенном выше примере x является первым позиционным аргументом. Мы также ввели этот аргумент как подтип Integer , это отражено в сигнатуре нашего нового метода:

methods(example)[1]
example(x::Integer) in Main at In[1]:1

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

function example(x::Integer = 4)

end

Обратите внимание, что необязательные позиционные аргументы, позиционные аргументы со значением по умолчанию, должны стоять после аргументов, которые не являются необязательными. Другими словами, мы не могли этого сделать…

function example(x::Integer = 5, y::Integer)

end

Вместо этого мы могли бы сделать это:

function example(y::Integer, x::Integer = 5)
end

Наконец, наши значения по умолчанию также могут быть вызовами методов. Например, мы могли бы сказать, что x должен быть равен y + 5:

function example(y::Integer, x::Integer = y + 5)
end

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

function example(y::Integer, x::Integer = y + 5; kw::Int64 = 2)
end

Обратите внимание, что любой аргумент после ; становится аргументом ключевого слова. Кроме того, нам нужно указать точку с запятой только один раз.

function example(y::Integer, x::Integer = y + 5; kw::Int64 = 2, dw::Int64 = 3)
end

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

function myfunc(x::Int64 ...)
    [println(n) for n in x]
end

X теперь меняется с Int64 на Tuple из них. Давайте попробуем это:

myfunc(5, 6, 7, 8)
5
6
7
8

Давайте посмотрим на тип, а также:

function myfunc(x::Int64 ...)
    println(typeof(x))
    [println(n) for n in x]
end
myfunc(5, 6, 7, 8)

NTuple{4, Int64}
5
6
7
8
4-element Vector{Nothing}:
 nothing
 nothing
 nothing
 nothing

Мы также можем предоставить кортеж этому методу, также используя ... :

myfunc((5, 2, 3) ...) 

mytupe = (1, 2, 3)

myfunc(mytupe ...)

Если бы мы предоставили такой кортеж без ... , вместо этого мы попытались бы предоставить Tuple как x , а не предоставить элементы Tuple как x . Это похоже на то, как если бы вы добавили Vector к другому Vector, когда хотели объединить значения векторов. Приведение этого знания к аргументам ключевых слов, очень мало изменений. Однако вместо того, чтобы быть добавленным к стандартному Tuple , он вернет Base.Pairs .

function myfunc(; args ...)
    println(typeof(args))
    println(args)
end
myfunc(x = 5)

Base.Pairs{Symbol, Int64, Tuple{Symbol}, NamedTuple{(:x,), Tuple{Int64}}}
Base.Pairs(:x => 5)

Это можно индексировать и работать с ним так же, как с Dict .

function myfunc(; args ...)
    println(args[:x])
end

myfunc(x = 5, y = 2)

5

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