2016-11-05 2 views
1

는 I은 모두 (1) 표시 인자를 필요로하며, (2) 파라미터 이름 가질 수줄리아라는 명명 된 매개 변수가 있어야합니까? 루비

이다
>> def f(x:) 
>> x + 1 
>> end 

>> f() 
ArgumentError: missing keyword: x 
>> f(2) 
ArgumentError: wrong number of arguments (given 1, expected 0) 
>> f(x:7) 
=> 8 

, I는, 를 인수를 전달 I 가지고 을 사용하여 연관된 매개 변수 이름을 제공하십시오.

내가 파이썬에서 같은 작업을 수행 할 수 있습니다

1> func f(x: Int) -> Int {return x + 1} 
2> f() 
error: missing argument for parameter 'x' in call 
2> f(3) 
error: missing argument label 'x:' in call 
2> f(x:7) 
$R0: Int = 8 

하지만 줄리아에서이 작업을 수행하는 방법을 알아낼 수 없습니다 :

>>> def f(*, x): 
... return x + 1 
... 
>>> f() 
TypeError: f() missing 1 required keyword-only argument: 'x' 
>>> f(3) 
TypeError: f() takes 0 positional arguments but 1 was given 
>>> f(x=7) 
8 

을 그리고, 좋은 측정을 위해, 심지어 스위프트는이 작업을 수행 할 수 있습니다. 키워드 인수는 호출 될 때 기본 매개 변수를 사용해야하는 것 같습니다. 이것이 맞습니까? 아니면 위의 Ruby와 Python 예제를 시뮬레이션 할 수있는 방법이 있습니까?

답변

5

올바른 내용입니다. 줄리아에서 필수 키워드 인수를 사용할 수 없습니다. 키워드 어구는 선택적 인수의 특별한 유형입니다. 하나는 위치가 아닌 이름으로 설정됩니다. (이 관련 : 당신은 이름이 아닌 키워드 인수를 설정할 수 없습니다 - 당신은 파이썬과 C#으로 할 수 있습니다.)

당신은 @amrods 제안으로 런타임에이를 보장 할 수

.

나는 그들이 컴파일 유형에서, 발신자 알려진 (추정)한다 x의 입력하면

function f(; x = nothing) 
    x===nothing && error("x not set.") 
    #... 
end 

와 그 체크 아웃 최적화되도록 할 것입니다.

그러나 실제로 런타임까지 적용되지 않습니다. 또한 @Fengyang을 사용할 수도 있습니다. very elegant way to achieve the same.

아마도 함수를 생성 된 함수로 바꾸면 컴파일시이를 적용 할 수 있습니다. 그러나 그것은 끔찍한 해킹이다.

+1

당신은'아무것도 안된다. – amrods

+0

@ amrods thanks, fixed. –

+0

물론 파이썬과 루비는 동적 언어처럼 런타임시 정확성을 보장합니다. –

2

이 방법이 유용할까요?

function f(; x = nothing) 
    x + 1 
end 

기본적으로 기본 초기 값을 제공합니다.

편집 : 기본값을 nothing으로 설정하십시오.

6

루비 또는 파이썬과 같은 방법으로 가능합니다. 사실,이 메시지는 매우 간단 할 수 있습니다.

julia> f(x, y; z=error()) = 1 
f (generic function with 1 method) 

julia> f(1, 2) 
ERROR: 
in f(::Int64, ::Int64) at ./REPL[65]:1 

그러나이 오류 메시지는 끔찍합니다. 그래서 우리는 더 나은 오류 던질 수 : oxinabox 언급 한 바와 같이, 오류가 런타임 대신 컴파일시에 발견

julia> f(x, y; z=throw(ArgumentError("z is required"))) = x + y + z 
f (generic function with 1 method) 

julia> f(1, 2) 
ERROR: ArgumentError: z is required 
in f(::Int64, ::Int64) at ./REPL[25]:1 

julia> f(1, 2, z=3) 
6 

을, 그러나 이것은 파이썬이나 루비와 동일합니다.이 너무 자세한 경우

, 매크로 쉽게 만들 : 다음

macro required(ex) 
    esc(Expr(:kw, ex, :(throw(ArgumentError("$($("$ex")) is required")))) 
end 

당신이 할 수

julia> foo(x, y; @required(z), @required(w), n=4) = x + y + z + w + n 
foo (generic function with 1 method) 

julia> foo(1, 2) 
ERROR: ArgumentError: z is required 
in foo(::Int64, ::Int64) at ./REPL[59]:1 

julia> foo(1, 2, z=3) 
ERROR: ArgumentError: w is required 
in (::#kw##foo)(::Array{Any,1}, ::#foo, ::Int64, ::Int64) at ./<missing>:0 

julia> foo(1, 2, z=3, w=4) 
14 

julia> foo(1, 2, z=3, w=4, n=5) 
15 

이 작동하는 이유는 인수를 전달되지 않을 때 기본 인수가 평가된다는 것입니다 . 기본 인수가 성공적으로 평가되지 않도록함으로써 사용자가 인수를 전달해야합니다.

+0

기본값을 지정하지 않으면 기본 인수의 RHS가 계산된다는 사실을 사용하는 것이 매우 영리한 방법입니다. –

+0

참으로 영리합니다. 런타임 시까 지 기본값을 평가하지 않으므로 새로 고칩니다. 파이썬이 기본 인수 (특히 변경 가능한 것들)에 대한 이상한 규칙으로 많은 사람들이 그랬던 것처럼 오래전에 불타 버렸습니다. 사랑스러운 매크로 BTW. –

관련 문제