В компьютерном программировании именованные параметры , аргументы с именованными параметрами , именованные аргументы или ключевые аргументы относятся к поддержке компьютерным языком вызовов функций для четкой связи каждого аргумента с заданным параметром в вызове функции.
Вызов функции с использованием именованных параметров отличается от обычного вызова функции тем, что аргументы передаются путем связывания каждого из них с именем параметра, а не путем предоставления упорядоченного списка аргументов.
Например, рассмотрим этот вызов метода Java или C# , который не использует именованные параметры:
window.addNewControl ( "Заголовок " , 20 , 50 , 100 , 50 , true ) ;
Используя именованные параметры в Python , вызов можно записать так:
window.addNewControl ( title = " Заголовок " , xPosition = 20 , yPosition = 50 , ширина = 100 , высота = 50 , drawingNow = True )
Используя именованные параметры в PHP , вызов можно записать так:
$window -> addNewControl ( title : "Заголовок" , xPosition : 20 , yPosition : 50 , width : 100 , height : 50 , drawingNow : True );
Версия с позиционными аргументами более неявная. Версии, в которых указаны параметры, более явные. В зависимости от обстоятельств программист может посчитать одну или другую более удобной для чтения.
Именованные параметры поддерживаются явно во многих языках. Неполный список примеров включает Ada , [1] C# 4.0+ , [2] Ceylon [ требуется ссылка ] , ColdFusion Markup Language (CFML) [ требуется ссылка ] , Common Lisp , [3] Fortran [ требуется ссылка ] , IDL [ требуется ссылка ] , Kotlin , [4] Mathematica [ требуется ссылка ] , PL/SQL [ требуется ссылка ] , PowerShell [ требуется ссылка ] , Python , [5] R , [6] PHP , [7] Ruby , [8] Scala , [9] Smalltalk [ требуется ссылка ] , Swift [10] и Visual Basic . [11] Objective-C не имеет именованных параметров (хотя части имени метода могут выглядеть как именованные параметры). [12]
В C++ можно получить именованные параметры, используя назначенные инициализаторы, начиная с C++20 , [13] например так:
структура A { int a {}, int b {} }; void foo ( A bar ) { std :: cout << bar.a << bar.b ; } foo ( { .a = 1 , .b = 3 } ) ;
В языках, не поддерживающих именованные параметры, порядок аргументов в вызове функции обязательно фиксирован, поскольку это единственный способ, с помощью которого язык может определить, какой аргумент предназначен для использования с каким параметром.
С именованными параметрами обычно можно предоставить аргументы в любом порядке, поскольку имя параметра, прикрепленное к каждому аргументу, определяет его цель. Это снижает согласованность между частями программы. Некоторые языки поддерживают именованные параметры, но все равно требуют предоставления аргументов в определенном порядке.
Именованные параметры часто используются вместе с необязательными параметрами. Без именованных параметров необязательные параметры могут появляться только в конце списка параметров, поскольку нет другого способа определить, какие значения были пропущены. Однако в языках, которые поддерживают именованные необязательные параметры, программы могут предоставлять любое подмножество доступных параметров, а имена используются для определения того, какие значения были предоставлены.
Дополнительная сложность возникает в таких языках, как OCaml , которые поддерживают как необязательные именованные параметры, так и частичное применение . В общем случае невозможно отличить частично примененную функцию от функции, к которой предоставлено подмножество параметров. OCaml разрешает эту неоднозначность, требуя позиционный аргумент после всех необязательных именованных аргументов: его наличие или отсутствие используется для определения того, была ли функция применена полностью или частично. Если все параметры необязательны, разработчик может решить проблему, добавив фиктивный позиционный параметр типа unit .
В языках, не поддерживающих именованные параметры, некоторые из тех же преимуществ могут быть достигнуты другими способами.
Их ценность в качестве документации может быть воспроизведена с помощью всплывающих подсказок в интегрированных средах разработки (IDE) для таких языков, как Java , или с помощью комментариев (в C ):
MyFunctionCall ( 20 , /* координата x */ 50 , /* координата y */ 100 , /* ширина */ 5 , /* высота */ TRUE /* рисуем сейчас? */ );
Такие комментарии не проверяются на корректность, и порядок аргументов остается важным.
Устранение ограничения на порядок аргументов и возможность оставлять некоторые значения неуказанными можно осуществить, передав запись или ассоциативный массив .
Например, в JavaScript эти два вызова эквивалентны:
MyFunctionCall ({ xPosition : 20 , yPosition : 50 , width : 100 , height : 5 , drawingNow : true });
MyFunctionCall ({ ширина : 100 , высота : 5 , xPosition : 20 , yPosition : 50 , drawingNow : true });
Сравните с C99: [14]
struct MyParam { int xPosition ; int yPosition ; int width ; int height ; unsigned char drawingNow ; }; … Параметры MyParam = { . xPosition = 20 , . yPosition = 50 , . width = 100 , . height = 5 , . drawingNow = TRUE }; MyFunctionCall ( & параметры );
В Perl и Ruby до 2.0 существует похожее соглашение (обычно называемое хешем или хешем опций [15] ), со специальной поддержкой пропуска разделителей в вызовах функций. Например, функция Net::FTP нового ядра модуля принимает хеш необязательных аргументов. [16]
В объектно-ориентированных языках программирования можно использовать цепочку методов для имитации именованных параметров как форму текучего интерфейса . Каждый аргумент именованного параметра заменяется методом на объекте «аргументы», который изменяет и затем возвращает объект. В C++ это называется идиомой именованных параметров . [17] Затем объект может быть передан функции, которая использует содержащиеся в нем аргументы.
Цепочка методов часто используется совместно с шаблоном конструктора как способ переопределения значений по умолчанию, предоставляемых классом конструктора.