このような関数を考えると
(define (foo) (values 1 2 3))
どういうわけか呼び出し(foo)
て、値の 1 つだけを取得でき(first (foo))
ますか? このためのヘルパー関数を定義することを考えましたが、呼び出された関数のアリティと一致する必要があり、適切ではありません。
(define (first x y z) x)
(first (foo))
このような関数を考えると
(define (foo) (values 1 2 3))
どういうわけか呼び出し(foo)
て、値の 1 つだけを取得でき(first (foo))
ますか? このためのヘルパー関数を定義することを考えましたが、呼び出された関数のアリティと一致する必要があり、適切ではありません。
(define (first x y z) x)
(first (foo))
簡単な方法は、 を使用define-values
して 3 つの値すべてをバインドし、次の 2 つを無視することです。しかし、これは少し不満です。を使用match-define-values
すると、他の 2 つを明示的に無視できるようになります。
(match-define-values (a _ _) (values 1 2 3))
それでも、最初の値を取得するためだけに、複数の値を返す関数を別の関数でラップできるわけではありません。
Racket は実際には、複数の値を操作するための組み込み機能をあまり提供していません。これは実際には設計によるものです。他のパッケージには、必要な機能が含まれている場合があります。たとえば、sugar
パッケージにはvalues->list
.
(first (values->list (values 1 2 3)))
これがコア ライブラリにないのには理由があります。これはアンチパターンです。関数から複数の値を返すことは、おそらく慎重に行うべきことです。Racket の多くの関数が複数の値を返すことはありません。これは、プログラムを推論するのが難しくなるためです。彼らはうまく構成できず、問題に対する最善の解決策になることはめったにありません.
複数の戻り値が役立つ状況があります。それは通常、パフォーマンス上の理由から一度に 2 つのことを行う関数を作成する場合です。たとえば、とquotient/remainder
の値を返すだけですが、単一の関数で実行されるため、より効率的に実装できます。同様に、は と の両方を呼び出すのと同じですが、より効率的です。quotient
remainder
split-at
take
drop