다음: 변수 길이 매개변수 목록, 이전: 함수 정의하기, 상위 문서: 함수와 대본   [차례][찾아보기]


11.3 다중 반환값

다른 많은 전산기 언어와 달리, 옥타브에서는 함수가 값 한 개 이상을 반환할 수 있습니다. 값을 여러 개 반환하는 함수를 정의하는 구문은 아래와 같습니다.

function [반환-목록] = 이름 (매개변수-목록)
  몸체
endfunction

이름, 매개변수-목록, 몸체는 반복문에서 설명한 바와 똑같으며, 반환-목록은 변수 이름을 반점으로 구분한 목록으로 함수가 반환할 값을 담습니다. 반환값 목록은 적어도 원소가 한 개 있어야 합니다.  반환-목록에 원소가 한 개만 있는 function문은 이전 절에서 기술한 것과 같습니다.

벡터에서 가장 크기가 큰 원소와 벡터에서  원소에서 가장 크기가 큰 원소가 처음 등장하는 위치인 값 두 개를 반환하는 함수 예시입니다.

function [max, idx] = vmax (v)
  idx = 1;
  max = v (idx);
  for i = 2:length (v)
    if (v (i) > max)
      max = v (i);
      idx = i;
    endif
  endfor
endfunction

특히 이 경우에, 두 값을 단일 배열의 원소로서 반환할 수도 있지만, 항상 가능하거나 편리하지는 않습니다. 반환될 값의 차원이 호환하지 않을 가능이 있어, 각 반환값에 다른 이름을 주는 것이 바람직합니다.

nthargout 함수를 반환값 일부나 여러 개를 한 번에 낱칸 배열에 담아 얻는 데에 사용할 수 있습니다. 낱칸 배열 객체를 참고하십시오.

nthargout (n, 함수, …)
nthargout (n, 개수, 함수, …)

함수 다루개나 문자열 함수에 지정한 함수의 n번째 출력 매개변수를 반환합니다.

추가 매개변수는 바로 함수로 전달합니다. 함수에 전달하는 매개변수의 총 개수는 개수에 지정하며, 개수의 기본 값은 n입니다. n은 출력 색인인 벡터일 수 있으며, 이 경우에는 요청한 출력 매개변수를 낱칸 배열에 추력합니다.

nthargout의 용도는 중간 변수를 피하는 것입니다. 예를 들어, 행렬의 최대 어귀 색인을 찾는다고 할 때, 아래 두 nthargout 구성은

m = magic (5);
cell2mat (nthargout ([1, 2], @ind2sub, size (m),
                     nthargout (2, @max, m(:))))
⇒ 5   3

아래 줄과 완벽하게 같습니다.

m = magic (5);
[~, idx] = max (M(:));
[i, j] = ind2sub (size (m), idx);
[i, j]
⇒ 5   3

아래 방식으로 모든 출력 매개변수를 낱칸 하나에 담는 것이 좋을 수도 있습니다.

USV = nthargout ([1:3], @svd, hilb (5));

같이 보기: nargin, nargout, varargin, varargout, isargout.

함수를 호출할 때마다 nargin 뿐만 아니라, nargout도 함수가 반환할 값의 개수로 자동 초기화합니다. 이를 통하여 함수 사용자가 요청한 반환값 개수에 따라 다르게 기능하는 함수를 작성할 수 있습니다. 내장 변수 ans에의 묵시적 할당은 출력 매개변수 개수에 포함하지 않아 nargout가 0 입니다.

svd lu 함수가 nargout값에 따라 다르게 작동하는 내장 함수 예시 입니다.

반환값의 일부만 있는 함수도 작성 가능합니다. 아래 함수를

function [x, y, z] = f ()
  x = 1;
  z = 2;
endfunction

아래처럼 호출하면,

[a, b, c] = f ()

아래처럼 출력합니다.

a = 1

b = [](0x0)

c = 2

그리고 오류도 나옵니다.

nargout ()
nargout (함수)

함수가 반환하는 값 개수를 보고합니다.

함수 안에서 호출하면, 호출자가 받기를 기대하는 값 개수를 반환합니다. 최상위 단계에서 매개변수 없이 호출하면, 행동이 정의되지 않아 오류가 발생합니다.

함수 이름 또는 함수 다루개인 선택 매개변수 함수와 호출하면, 함수가 내보내기로 선언한 출력값 개수를 반환합니다.

마지막 출력 매개변수가 varargout이면, 반환값이 음수 입니다.

예를 들면,

f ()

위 함수는 f 함수 안에서 nargout이 0을 반환하고,

[s, t] = f ()

위 함수는 f 함수 안에서 nargout이 2를 반환합니다.

두 번째 용법에서는,

nargout (@histc)   # 또는 문자열 입력에는 nargout ("histc")

histc의 출력이 두 개이기 때문에 2를 반환하지만,

nargout (@imread)

histc의 출력이 두 개이나 두 번째 출력이 varargout이기 때문에 -2를 반환합니다.

풀그림 짜기 안내: nargout는 내장 함수에는 작동하지 않으며, 모든 익명 함수에 대하여 -1을 반환합니다.

같이 보기: nargin, varargout, isargout, nthargout.

함수 머리에서 호출이 올바른지 확인하는 것이 좋습니다. 옥타브에서 아래 표현은

if (nargin < min_#_inputs || nargin > max_#_inputs)
  print_usage ();
endif

입력 개수가 틀렸을 때, 함수 실행을 멈추고, 함수를 호출하는 올바른 방법을 안내하는 데에 자주 쓰입니다.

매트랩과의 호환을 위하여, 비슷한 오류 확인 기능을 제공하는 narginchk, nargoutchk도 사용 가능합니다.

narginchk (최소_개수, 최대_개수)

입력 매개변수 개수가 올바른지 확인합니다.

최소_개수최대_개수 범위 밖인 매개변수 개수로 함수를 호출하면, 오류 문구를 생성합니다. 개수가 맞으면 아무 역할도 안 합니다.

최소_개수최대_개수는 반드시 스칼라 수치 값이어야 합니다. 0, 무한대, 음수도 가능하며, 최소_개수최대_개수가 같아도 됩니다.

이 함수가 nargin를 호출자로서 평가함에 유의하십시오.

같이 보기: nargoutchk, error, nargout, nargin.

nargoutchk (최소_개수, 최대_개수)
msgstr = nargoutchk (최소_개수, 최대_개수, nargs)
msgstr = nargoutchk (최소_개수, 최대_개수, nargs, "string")
msgstruct = nargoutchk (최소_개수, 최대_개수, nargs, "struct")

출력 매개변수 개수가 올바른지 확인합니다.

첫 번째 형식은, 매개변수 개수가 최소_개수최대_개수 사이가 아니면 오류를 반환합니다. 개수가 맞으면 아무 역할도 안 합니다. 이 함수가 nargout의 값을 호출자로서 평가하므로 nargout의 값이 바뀌지 않도록 유의하십시오.

최소_개수최대_개수는 반드시 스칼라 수치 값이어야 합니다. 0, 무한대, 음수도 가능하며, 최소_개수최대_개수가 같아도 됩니다.

하위 호환을 위하여, 요청한 출력 개수가 올바르지 않으면, 그외 형식도 적절한 오류 문구 문자열(또는 구조체)을 반환합니다.

함수에 전달되는 출력 매개변수의 개수가 허용 범위 안인지 확인하는 것이 유용합니다.

같이 보기: narginchk, error, nargout, nargin.

매개변수 개수 외에도 입력의 속성도 확인할 수 있습니다. validatestring은 문자열 매개변수용이고, validateattributes은 수치 매개변수용 입니다.

격_문자열 = validatestring (문자열, 문자열_배열)
적격_문자열  = validatestring (문자열, 문자열_배열, 함수_이름)
적격_문자열  = validatestring (문자열, 문자열_배열, 함수_이름, 변수_이름)
적격_문자열  = validatestring (…, 자리)

문자열문자열_배열에 있는 원소 또는 원소의 부분열인지 확인합니다.

시험할 문자열이 문자 배열이고 문자열_배열이 올바른 낱칸 배열인 문자열이면, 적격_문자열문자열로 시작하는 적격_문자열의 항목 또는 부분열로 정의되어, 문자열의 적격한 형태가 됩니다. "r"을 긴 형태인 "red"으로 바꾸는 등 짧은 선택지를 검토하고 확장하는 데에 유용합니다. 문자열 적격_문자열의 부분열이고, 일치하는 경우가 여러 번일 때, 모든 일치가 다른 일치의 부분열이면 가장 짧은 일치만 반환합니다. 모든 일치가 다른 일치의 부분열이 아니면, 문자열의 확장이 무엇인지 애매하기에 오류가 발생합니다. 모든 비교는 대소문자를 구분합니다.

추가 입력 함수_이름, 변수_이름, 자리는 모든 오류 문구를 더 구체적으로 만듭니다.

예시:

validatestring ("r", {"red", "green", "blue"})
⇒ "red"

validatestring ("b", {"red", "green", "blue", "black"})
⇒ error: validatestring: multiple unique matches were found for 'b':
   blue, black

같이 보기: strcmp, strcmpi, validateattributes, inputParser.

validateattributes (A, 분류, 속성)
validateattributes (A, 분류, 속성, 매개변수_색인)
validateattributes (A, 분류, 속성, 함수_이름)
validateattributes (A, 분류, 속성, 함수_이름, 매개변수_이름)
validateattributes (A, 분류, 속성, 함수_이름, 매개변수_이름, 매개변수_색인)

입력 매개변수의 적격성을 판별합니다.

매개변수 A분류 중 하나에 속하고, 모든 속성을 담을 수 있는지 확인합니다. 속하지 않거나 담을 수 없으면, 상황에 맞는 정형화된 오류 문구를 나옵니다. 오류 문구를 함수 이름 함수_이름과 매개변수 이름 매개변수_이름, 입력에서의 매개변수의 자리 매개변수_색인으로 더 완전하게 할 수 있습니다.

분류는 반드시 분류의 이름을 담은 낱칸 배열인 문자열(빈 낱칸 배열도 가능)이어야 합니다.(분류 이름이 대소문자를 구분함을 잊지 마십시오.). 분류 이름 밖에도, 다음 범주 이름도 유효합니다.

"float"

"double""single"를 포괄하는 떠돌이 소수점 값 입니다.

"integer"

(u)int8, (u)int16, (u)int32, (u)int64를 포괄하는 정수 값 입니다.

"numeric"

떠돌이 소수점과 정수를 포괄하는 수치 값 입니다.

속성은 반드시 A를 검사하기 위한 이름을 담은 낱칸 배열이어야 합니다. 일부는 사용하려면 이름 오른쪽에 추가적인 값이 필요합니다(개별 특기 사항을 보십시오.).

"<="

모든 값이 다음 값 이하 입니다.

"<"

모든 값이 다음 값 미만 입니다.

">="

모든 값이 다음 값 이상 입니다.

">"

모든 값이 다음 값 초과 입니다.

"2d"

2차원 배열 입니다. 길이가 1이거나 0인 벡터와 빈 행렬도 2차원입니다.

"3d"

3차원을 넘지 않습니다. 2차원 행렬도 3번째 차원이 1인 3차원 행렬입니다.

"binary"

모든 값이 1아니면 0 입니다.

"column"

값을 열 하나에 정렬할 수 있습니다.

"decreasing"

NaN인 값이 없고, 각 값이 자기 앞 값보다 작습니다.

"diag"

값이 대각행렬입니다.

"even"

모든 값이 짝수 입니다.

"finite"

모든 값이 무한대입니다.

"increasing"

NaN인 값이 없고, 각 값이 자기 앞 값보다 큽니다.

"integer"

모든 값이 정수입니다. 정수형 여부를 가리는 isinteger과 다릅니다. A의 개별 값이 소수가 없는 등의 정수 값인지 확인합니다.

"ncols"

다음 값과 정확하게 같은 수의 열이 있습니다.

"ndims"

다음 값과 정확하게 같은 수의 차원이 있습니다.

"nondecreasing"

NaN인 값이 없고, 각 값이 자기 앞 값 이상 입니다.

"nonempty"

비지 않았습니다.

"nonincreasing"

NaN인 값이 없고, 각 값이 자기 앞 값 이하 입니다.

"nonnan"

NaN인 값이 없습니다.

"nonnegative"

모든 값이 음이 아닙니다.

"nonsparse"

희소행렬이 아닙니다.

"nonzero"

0이 없습니다.

"nrows"

다음 값과 정확하게 같은 수의 행이 있습니다.

"numel"

다음 값과 정확하게 같은 수의 원소가 있습니다.

"odd"

모든 값이 홀수입니다.

"positive"

모든 값이 양수입니다.

"real"

복소수가 아닌 행렬입니다.

"row"

값을 행 하나에 정렬할 수 있습니다.

"scalar"

스칼라입니다.

"size"

다음 값과 길이가 정확하게 같습니다. 다음 값이 반드시 각 차원의 길이가 있는 배열이어야 합니다. NaN 값을 사용하여 특정 차원에 대한 검사를 건너뜁니다.

"square"

정방행렬입니다.

"vector"

값을 벡터 하나에 정렬할 수 있습니다.(벡터 또는 열)

같이 보기: isa, validatestring, inputParser.

위 함수로 충분하지 않으면, 굉장히 복잡한 함수 입력 검사를 수행하는 분류 inputParser도 있습니다.

p = inputParser ()

Create object p of the inputParser class.
inputParser 분류인 객체 p를 만듭니다.

이 분류는 함수 매개변수를 쉽게 분석하기 위하여 설계되었습니다. 이 분류는 아래 네 가지 형식의 매개변수를 지원합니다.

  1. 필수(addRequired 참고);
  2. 선택 사항(addOptional 참고);
  3. 이름 짓기(addParameter 참고);
  4. 엇바꿈 (addSwitch 참고).

함수 무른모 사이틀을 이 방법으로 정의하고 나면, 전달받은 매개변수를 parse 방식으로 구문 분석하고, Results 접근기로 분석한 결과에 접근합니다.

inputParser.Parameters

이미 정의한 매개변수 이름 목록을 반환합니다.

inputParser.Results

기록란 이름과 대응하는 값이 매개변수 이름인 구조체를 반환합니다.

inputParser.Unmatched

Results와 비슷하게 구조체를 반환하지만, 일치하지 않는 매개변수용 입니다. KeepUnmatched 속성을 참고하십시오.

inputParser.UsingDefaults

기본값을 사용하는 매개변수의 이름을 낱칸 배열에 담아 반환합니다.

inputParser.CaseSensitive = 논리값

매개변수 이름 비교에서 대소문자 구분 여부를 결정합니다. 기본값은 거짓입니다.

inputParser.FunctionName = 이름

오류 문구에 사용할 함수 이름을 설정합니다. 기본값은 빈 문자열입니다.

inputParser.KeepUnmatched = 논리값

정의하지 않은 매개변수에 관한 오류를 제공할지를 결정합니다. 기본값은 거짓입니다. 참으로 설정하면, 추가 매개변수에 parse 방법 후에 Unmatched으로 접근합니다. SwitchParameter 매개변수를 섞어 사용할 수 있기 때문에, 일치하지 않는 형식에 대해서는 알 수 없습니다. 매개변수가 일치하지 않는 것으로 판명되면, Parameter 형식으로 가정되어 값 뒤에 온다고 예상합니다.

inputParser.StructExpand = 논리값

구조체가 매개변수/값 쌍 대신 함수에 전달될 수 있는지 결정합니다. 기본값은 참입니다.

아래 예시가 이 분류의 사용 방법을 보여줍니다.

function check (varargin)
  p = inputParser ();                      # 객체 생성
  p.FunctionName = "check";                # 함수 이름 짓기
  p.addRequired ("pack", @ischar);         # 필수 매개변수
  p.addOptional ("path", pwd(), @ischar);  # 선택 매개변수

  ## 함수 다루개를 검증자에 사용하기 위하여 익명 함수로 만듭니다.
  val_mat = @(x) isvector (x) && all (x <= 1) && all (x >= 0);
  p.addOptional ("mat", [0 0], val_mat);

  ## "Parameter"형인 매개변수 두 개를 만듭니다.
  val_type = @(x) any (strcmp (x, {"linear", "quadratic"}));
  p.addParameter ("type", "linear", val_type);
  val_verb = @(x) any (strcmp (x, {"low", "medium", "high"}));
  p.addParameter ("tolerance", "low", val_verb);

  ## 매개변수의 Switch형을 만듭니다.
  p.addSwitch ("verbose");

  p.parse (varargin{:});  # 만든 구문 분석기를 입력에 기능합니다.

  ## 함수의 나머지 부분은 p.Results로 입력에 접근합니다.
  ## 오차 허용 입력을 p.Results.tolerance으로 받는 식입니다.
endfunction
check ("mech");           # 올바름. 다른 매개변수에는 기본값 사용
check ();                 # 잘못됨. 매개변수가 한 개 있어야 함
check (1);                # 잘못됨. ! ischar부터
check ("mech", "~/dev");  # 올바름.  다른 매개변수에는 기본값 사용

check ("mech", "~/dev", [0 1 0 0], "type", "linear");  # 올바름

## 아래 또한 올바릅니다. Switch 매개변수형을
## Parameter 매개변수형 앞이나 속에 넣는 방법에 유의하십시오.
## (하지만, Switch 매개변수형은 여전히 추가 매개변수 맨 끝에 나타납니다.)
check ("mech", "~/dev", [0 1 0 0], "verbose", "tolerance", "high");

## 아래는 모든 선택 매개변수 `path'와 `mat'이
## 이름 지어진 매개변수 `type' 이전에 전달되기에 오류를 반환합니다. 
check ("mech", "~/dev", "type", "linear");

안내 1: 함수에 네 가지 무른모 사이틀을 모두 조합할 수 있지만, 특정 순서대로 조합하여야 합니다. Required 매개변수가 반드시 먼저 와야하고, 모든 Optional 매개변수가 뒤따를 수 있습니다. ParameterSwitch매개변수만이 순서가 없으며, 이 둘이 반드시 맨 뒤에 와야 합니다.

안내 2: OptionalParameter 매개변수가 모두 함수 무른모 사이틀 안에 들어가고, 문자열인 선택 매개변수가 검증에 실패하면, 실패한 그 지점이 Optional 매개변수의 끝으로 간주합니다. 남은 매개변수는 Parameter 또는 Switch 매개변수 모두와 비교됩니다.

같이 보기: nargin, validateattributes, validatestring, varargin.


다음: 변수 길이 매개변수 목록, 이전: 함수 정의하기, 상위 문서: 함수와 대본   [차례][찾아보기]