함수 인수에 대한 기본값 정의


86

Lua wiki에서 누락 된 인수에 대한 기본값을 정의하는 방법을 찾았습니다.

function myfunction(a,b,c)
    b = b or 7
    c = c or 5
    print (a,b,c)
end

그게 유일한 방법인가요? PHP 스타일 myfunction (a,b=7,c=5)이 작동하지 않는 것 같습니다. Lua 방식이 작동하지 않는다는 것이 아니라 이것이 유일한 방법인지 궁금합니다.

답변:


87

이름이 지정된 인수와 PHP 또는 Python과 같은 기본값을 원하는 경우 테이블 생성자를 사용하여 함수를 호출 할 수 있습니다.

myfunction{a,b=3,c=2}

(이는 LuaSocket의 고급 형식의 프로토콜 모듈IUPLua의 생성자 와 같은 Lua의 여러 위치에서 볼 수 있습니다 .)

함수 자체는 다음과 같은 서명을 가질 수 있습니다.

function myfunction(t)
    setmetatable(t,{__index={b=7, c=5}})
    local a, b, c =
      t[1] or t.a, 
      t[2] or t.b,
      t[3] or t.c
    -- function continues down here...
end

매개 변수 테이블에서 누락 된 값 __index은 메타 테이블 의 테이블에서 가져옵니다 (메타 테이블에 대한 설명서 참조 ).

물론 테이블 생성자와 함수를 사용하여보다 고급 매개 변수 스타일을 사용할 수 있습니다. 필요한 것은 무엇이든 작성할 수 있습니다. 예를 들어, 다음 은 매개 변수 이름과 기본값을 정의하는 테이블에서 명명 또는 위치 인수 테이블을 가져 오는 함수와 일반 인수 목록을 취하는 함수를 구성하는 함수입니다.

언어 수준이 아닌 기능으로 이러한 호출을 변경하여 새로운 동작 및 의미 체계를 제공 할 수 있습니다.

  • 둘 이상의 이름을 허용하도록 변수를 만들 수 있습니다.
  • 위치 변수와 키워드 변수는 산재 할 수 있으며 둘 다 정의하면 둘 중 하나에 우선 순위를 부여하거나 오류가 발생할 수 있습니다.
  • 키워드 전용 위치없는 변수와 이름없는 위치 전용 변수를 만들 수 있습니다.
  • 상당히 자세한 테이블 구성은 문자열을 구문 분석하여 수행 할 수 있습니다.
  • 함수가 하나의 테이블이 아닌 다른 것으로 호출되는 경우 인수 목록을 그대로 사용할 수 있습니다.

인수 변환기를 작성하는 데 유용한 몇 가지 함수는 unpack( table.unpack5.2에서 이동 ), setfenv(새 _ENV구성 으로 5.2에서 사용되지 않음 ) 및 select(주어진 인수 목록에서 단일 값을 반환하거나를 사용하여 목록의 길이를 반환 '#')입니다.


AI는 방금 lua를 사용하기 시작했습니다. 당분간 간단하게 유지하겠습니다.하지만 귀하의 게시물은 매우 유익합니다. 나중에 편리하게 사용할 수 있습니다. 감사.
ripat

1
대부분의 경우 단순하게 유지하는 것이 좋습니다. 메타 매개 변수 인터페이스는 많은 수의 선택적 속성 (예 : UI 개체)이있는 개체에만 실제로 필요합니다.
Stuart P. Bentley

이 대답은 현재 수락 된 것으로 표시된 것이 아니라 질문을 해결하는 사람이라고 생각합니다. 깨달음을 주셔서 감사합니다 :)
Undo

2
주목해야한다 x or default이 응답에 사용 된 표현이 매개 변수를 기본값으로 진정한 상당하지만 두 경우에만 작동하는지 그냥 간단한 해결 방법은 정말없는 nilfalse잘못된 매개 변수의 값은가. 부울 매개 변수의 기본값 xtrue이고 호출자가 명시 적 false. 그런 다음 명시 적으로 전달 되었지만 을 x or true제공합니다 . 더 나은 버전은 가독성이 더 좋습니다 . 그래도 명시적인 인수를 처리 할 수 ​​없습니다 . truefalseif x == nil then x = default endnil
Jesper

오, 이건 이제 받아 들여진 대답입니다! 좋은. (공식적으로, 그리고 맥락에서 취소의 코멘트 @ 넣어, jpjacobs의 대답은 아래에 아주 긴 시간 동안 허용 대답했다 : 나는 거의 가지고 두 번째 인민당 배지를 그 위에.)
스튜어트 P. 벤틀리

46

제 생각에는 다른 방법이 없습니다. 그것은 단지 Lua의 사고 방식입니다. 주름이없고, 약간의 통사론 적 설탕을 제외하고는 단순한 일을하는 중복 된 방법이 없습니다.


10
이 대답은 테이블 생성자로 함수를 호출하는 아래 Stuart P. Bentley의 대답에 의해 완전히 반증됩니다. 이것이 Lua의 강점 중 하나입니다. 주름이 많지는 않지만 Lua의 기본 구성 요소를 통해 무한한 작업을 수행 할 수 있습니다.
Colin D Bennett

@ColinDBennett 의견을 보내 주셔서 감사합니다. OP가 귀하의 의견을 읽은 것처럼 보였으며 그해 12 월 그에 따라 수락 된 답변을 변경했습니다. : 윙크 : (그리고 지금은 명확성을 위하여, "위 스튜어트 P. 벤틀리의 대답"입니다
스튜어트 P. 벤틀리

21

기술적 으로 는 (이 7 로 평가 되는 유효한 값인 b = b == nil and 7 or b경우에 사용해야 함 )이 있지만 이는 아마도 당신이 찾고있는 것이 아닐 것입니다.falsefalse or 7


1
를 확인하지 않는 경우 false더 간단한 방법은 변수를 먼저 배치하고 기본값을 마지막에 배치하는 것입니다. b = b or 7
Rebs

2
OP가 질문에서 언급했기 때문에 언급하는 것이 불필요하다고 생각했습니다 (질문은 이외의 기본 변수를 정의하는 방법에 관한 것입니다b = b or 7 ).
Stuart P. Bentley

6

지금까지 내가 찾은 유일한 방법은 다음과 같이하는 것입니다.

function new(params)
  params = params or {}
  options = {
    name = "Object name"
  }

  for k,v in pairs(params) do options[k] = v end

  some_var = options.name
end

new({ name = "test" })
new()
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.