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