문제

옵션이라는 이름의 인수가있는 함수를 정의하는 가장/표준적인 방법은 무엇입니까? 구체적으로 만들기 위해 기능을 만들어 봅시다 foo 명명 된 인수와 함께 a, b, 그리고 c, 기본값은 각각 1, 2 및 3입니다. 비교를 위해 여기에 버전이 있습니다 foo 위치 논쟁과 함께 :

foo[a_:1, b_:2, c_:3] := bar[a,b,c]

다음은 이름 지정된 연기 버전의 샘플 입력 및 출력입니다. foo:

foo[]                  --> bar[1,2,3]
foo[b->7]              --> bar[1,7,3]
foo[a->6, b->7, c->8]  --> bar[6,7,8]

물론 이름이 지정된 인수 전에 위치 주장을하기가 쉽습니다.

도움이 되었습니까?

해결책

Mathematica 문서에서 수행하는 표준 방법을 찾았습니다. http://reference.wolfram.com/mathematica/tutorial/settingupfunctionswithOptionalArguments.html

Options[foo] = {a->1, b->2, c->3};  (* defaults *)
foo[OptionsPattern[]] := bar[OptionValue@a, OptionValue@b, OptionValue@c]

매번 "옵션 value"를 입력하는 것은 약간 번거 롭습니다. 어떤 이유로 든 당신은 ov = OptionValue 그러나 당신은 이것을 할 수 있습니다 :

foo[OptionsPattern[]] := Module[{ov},
  ov[x___] := OptionValue[x];
  bar[ov@a, ov@b, ov@c]]

아니면 이거:

With[{ov = OptionValue},
  foo[OptionsPattern[]] := bar[ov@a, ov@b, ov@c]
]

아니면 이거:

$PreRead = ReplaceAll[#, "ov" -> "OptionValue"] &;

foo[OptionsPattern[]] := bar[ov@a, ov@b, ov@c]

다른 팁

예, OptionValue 마법에 의존하기 때문에 약간 까다로울 수 있습니다.

OptionValue[name] 동일합니다 OptionValue[f,name], 어디 f 변환 규칙의 왼쪽 머리입니다. OptionValue[name] 나타납니다.

명시 적으로 던지고 있습니다 Automatic 일반적으로 트릭을 수행하므로 귀하의 경우 솔루션은 다음과 같습니다.

Options[foo] = {a -> 1, b -> 2, c -> 3};
foo[OptionsPattern[]] := 
  bar @@ (OptionValue[Automatic, #] &) /@ First /@ Options[foo] 

그건 그렇고, 옵션은 opts:___?OptionQ, 그런 다음 수동으로 옵션 값을 찾습니다 {a,b,c}/.Flatten[{opts}]. 패턴 검사 OptionQ 여전히 주변에 있지만 (문서화되지는 않았지만) OptionValue 접근 방식은 존재하지 않는 옵션에 대한 경고를 받는다는 이점이 있습니다 (예 : foo[d->3]). 이것은 또한 두 번째 응답의 경우에도 해당되지만 수락 한 응답에는 그렇지 않습니다.

이 가능한 솔루션을 믹스에 넣을 것입니다.

foo[opts___Rule] := Module[{f},
  f@a = 1; (* defaults... *)
  f@b = 2;
  f@c = 3;
  each[a_->v_, {opts}, f@a = v];

  Return[bar[f@a, f@b, f@c]]
]

나는 그것의 간결함을 좋아하지만 그것이 표준적인 방법이라고 생각하지 않습니다. 그런 식으로하는 일이 있습니까?

추신 : 다음과 같은 편리한 유틸리티 기능을 사용합니다.

SetAttributes[each, HoldAll];                (* each[pattern, list, body]     *)
each[pat_, lst_, bod_] :=                    (*  converts pattern to body for *)
  Scan[Replace[#, pat:>bod]&, Evaluate@lst]  (*   each element of list.       *)
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top