Spec2.8Chap6c2

6.16 条件式 (Conditional Expressions)

構文:

   Expr1          ::=   'if' '(' Expr ')' {nl} Expr [[semi] 'else' Expr]

The conditional expression if (e1) e2 else e3 chooses one of the values of e2 and e3 , depending on the value of e1 . The condition e1 is expected to conform to type Boolean. The then-part e2 and the else-part e3 are both expected to conform to the expected type of the conditional expression. The type of the conditional expression is the weak least upper bound (§3.5.3) of the types of e2 and e3 . A semicolon preceding the else symbol of a conditional expression is ignored .

条件式 if (e1) e2 else e3 は、e1 の値に応じて、e2 と e3 の値の 1 つを選択します。 条件 e1 は Boolean 型に適合することが要請されます。 then 部分 e2 と else 部分 e3 は共に、 条件式の要請型に適合することが要請されます。 条件式の型は、e2 と e3 の型の、弱い最少の上限境界 (§3.5.3)です。 条件式の else シンボルの手前のセミコロンは無視されます。

The conditional expression is evaluated by evaluating first e1 . If this evaluates to true, the result of evaluating e2 is returned, otherwise the result of evaluating e3 is returned .

条件式は、はじめの e1 の評価に基づいて評価されます。 もしこの評価が true なら、e2 の評価が返されます。そうでなければ、 e3 評価結果が返されます。

A short form of the conditional expression eliminates the else-part. The conditional expression if (e1) e2 is evaluated as if it was if (e1) e2 else () .

条件式の短縮形として else 部分がない場合があります。 条件式 if (e1) e2 は、それが if (e1) e2 else () であるかのように評価されます。



6.17 while ループ式 (While Loop Expressions)

構文:

   Expr1          ::=   'while' '(' Expr ')' {nl} Expr

The while loop expression while (e1) e2 is typed and evaluated as if it was an application of whileLoop (e1) (e2) , where the hypothetical function whileLoop is defined as follows .

while ループ式 while (e1) e2 は、whileLoop (e1) (e2)の適用であるかのように 型付けされ評価されます。ただしここで、仮想関数 whileLoop は 次のように定義されます。

   def whileLoop(cond: => Boolean)(body: => Unit): Unit =
     if (cond) { body ; whileLoop(cond)(body) } else {}



6.18 do ループ式 (Do Loop Expressions)

構文:

   Expr1          ::=   'do' Expr [semi] 'while' '(' Expr ')'

The do loop expression do e1 while (e2) is typed and evaluated as if it was the expression (e1 ; while (e2) e1). A semicolon preceding the while symbol of a do loop expression is ignored .

do ループ式 do e1 while (e2)は、式 (e1 ; while (e2) e1)であるかのように 型付けされ評価されます。 do ループ式の while シンボルの前のセミコロンは無視されます。



6.19 for 内包表記と for ループ (For Comprehensions and For Loops)

構文:

   Expr1           ::=   'for' ('(' Enumerators ')' | '{' Enumerators '}')
                            {nl} ['yield'] Expr
   Enumerators     ::=   Generator {semi Enumerator}
   Enumerator      ::=   Generator
                     |   Guard
                     |   'val' Pattern1 '=' Expr
   Generator       ::=   Pattern1 '<-' Expr [Guard]
   Guard           ::=   'if' PostfixExpr

A for loop for (enums) e executes expression e for each binding generated by the enumerators enums. A for comprehension for (enums) yield e evaluates expression e for each binding generated by the enumerators enums and collects the results. An enumerator sequence always starts with a generator; this can be followed by further generators, value definitions, or guards. A generator p <- e produces bindings from an expression e which is matched in some way against pattern p. A value definition p = e binds the value name p (or several names in a pattern p) to the result of evaluating the expression e. A guard if e contains a boolean expression which restricts enumerated bindings. The precise meaning of generators and guards is defined by translation to invocations of four methods: map, withFilter, flatMap, and foreach. These methods can be implemented in different ways for different carrier types .

for ループ for (enums) e は、列挙子 enums によって生成された 各束縛に対して式 e を実行します。 for 内包表記 for (enums) yield e は、列挙子 enums によって生成された 各束縛に対して式 e を評価し、結果を集めます。 列挙子シーケンスは常に生成子から始まります。;その後に、さらなる生成子、 値定義、あるいはガードを続けることができます。 生成子 p <- e は、 パターン p に対して何らかの方法でマッチした式 e から、束縛を生み出します。 値定義 p = e は、値名 p(あるいは、パターン p 中のいくつかの名前)を 式 e の評価結果へ束縛します。 ガード if e は、列挙された束縛を限定する boolean 式を含みます。 生成子とガードの正確な意味は、4 つのメソッド map、withFilter、flatMap、 foreach 呼び出しへの変換によって定義されます: これらのメソッドは、異なるタイプに応じて異なる方法で実装されます。

The translation scheme is as follows. In a first step, every generator p <- e, where p is not irrefutable (§8.1) for the type of e is replaced by

変換方式は次の通りです。 最初のステップでは、全ての生成子 p <- e は次で置き換えられます (ここで p は e の型について明白(irrefutable)ではないとします (§8.1) )。

       p <- e.withFilter { case p => true; case _ => false }

次に、すべての内包表記がなくなるまで、以下の規則が繰り返し適用されます。

  • for 内包表記 for (p <- e) yield e´は e.map { case p => e´ } へ変換されます。
  • for ループ for (p <- e) e´は e.foreach { case p => e´ } へ変換されます。
  • for 内包表記
       for (p <- e ; p´ <- e´ ...) yield e´´

(ここで ... は、生成子、定義、あるいはガードの(空きでもよい)並び) は、次へ変換されます。

       e.flatMap { case p => for (p´ <- e´ ...) yield e´´ } 
  • for ループ
         for (p <- e ; p´ <- e´ ...) e´´ 

(ここで ... は、生成子、定義、あるいはガードの(空きでもよい)並び) は、次へ変換されます。

       e.foreach { case p => for (p´ <- e´ ...) e´´ } 
  • A generator p <- e followed by a guard if g is translated to a single generator p <- e.withFilter((x1,...,xn) => g) , where x1,...,xn are the free variables of p .
  • A generator p <- e followed by a value definition p´ = e´ is translated to the following generator of pairs of values, where x and x are fresh names:
  • ガード if g が後に続く生成子 p <- e は、ただ1つの生成子 p <- e.withFilter((x1,...,xn) => g)へ変換されます。ここで x1,...,xn は p の自由変数です。
  • 値定義 p´ = e´が後に続く生成子 p <- e は、次の、値の対の生成子へ変換されます。ここで x と x´ は新規の名前です:
       (p , p´) <- for (x@p <- e) yield { val x´@p´ = e´ ; (x , x´) }


Example 6.19.1 : 次のコードは、その和が素数である、 1 以上 n - 1 以下の数の全ての対を作り出します。

   for  { i <- 1 until n
          j <- 1 until i
          if isPrime(i+j)
   } yield (i, j)

for 内包表記は次へ変換されます。

   (1 until n)
     .flatMap {
        case i => (1 until i)
          .withFilter { j => isPrime(i+j) }
          .map { case j => (i, j) } }


Example 6.19.2 : for 内包表記は、ベクトルと行列アルゴリズムを簡潔に表現するのに役立ちます。 例えば、次は与えられた行列の転置を計算する関数です。:

   def transpose[A](xss: Array[Array[A]]) = {
     for (i <- Array.range(0, xss(0).length)) yield
       for (xs <- xss) yield xs(i)
   }

次は、2 つのベクトルのスカラ積を計算する関数です。:

   def scalprod(xs: Array[Double], ys: Array[Double]) = {
     var acc = 0.0
     for ((x, y) <- xs zip ys) acc = acc + x * y
     acc
   }

最後に、次は 2 つの行列の積を計算する関数です。 Example 6.15.1 の 命令型バージョンと比較してみてください。

   def matmul(xss: Array[Array[Double]], yss: Array[Array[Double]]) = {
     val ysst = transpose(yss)
     for (xs <- xss) yield
       for (yst <- ysst) yield
         scalprod(xs, yst)
   }

上記のコードは、map、flatMap、withFilter、foreach がクラス scala.Array のインスタンスに対して定義されている、 という事実を利用しています。



6.20 return 式 (Return Expressions)

構文:

   Expr1        ::=   'return' [Expr]

A return expression return e must occur inside the body of some enclosing named method or function . The innermost enclosing named method or function in a source program, f , must have an explicitly declared result type, and the type of e must conform to it .

return 式 return e は、 取り囲む名前付きメソッド/関数本体の内側に現れなくてはなりません。 ソースプログラム中の、取り囲む最内の名前付きメソッド/関数 f は、 明示的に宣言された結果型を持たなければならず、 e の型はそれに適合しなくてはなりません。 return 式は式 e を評価し、その値を f の結果として返します。 return 式の後に続く、どのような文あるいは式の評価も除かれます。 return 式の型は scala.Nothing です。

式 e は省略されるかもしれません。 return 式 return は、型チェックされ、return ()であるかのように評価されます。

無名関数の展開としてコンパイラが生成する apply メソッドは、 ソースプログラム中の名前付き関数としては扱われず、 従って、return 式のターゲットには決してなりません。

Returning from a nested anonymous function is implemented by throwing and catching a scala.runtime.NonLocalReturnException . Any exception catches between the point of return and the enclosing methods might see the exception . A key comparison makes sure that these exceptions are only caught by the method instance which is terminated by the return .

ネストした無名関数から戻ることは、scala.runtime.NonLocalReturnException の送出と捕捉として実装されます。 return の場所と取り囲むメソッド間のどのような例外捕捉も、例外となるでしょう。 キーを比較すれば、これらの例外が return によって終了するメソッドインスタンスによってのみ捕捉できる、 ということを確かめることができます。

If the return expression is itself part of an anonymous function, it is possible that the enclosing instance of f has already returned before the return expression is executed . In that case, the thrown scala.runtime.NonLocalReturnException will not be caught, and will propagate up the call stack .

もし return 式がそれ自身無名関数の一部なら、f の取り囲むインスタンスは return 式が実行される前にさっさと戻ることが可能です。 そのような場合、送出された scala.runtime.NonLocalReturnException は捕えられません。そして、呼び出しスタックは増殖し続けます。



6.21 throw 式 (Throw Expressions)

構文:

   Expr1       ::=   'throw' Expr

A throw expression throw e evaluates the expression e . The type of this expression must conform to Throwable . If e evaluates to an exception reference, evaluation is aborted with the thrown exception . If e evaluates to null, evaluation is instead aborted with a NullPointerException . If there is an active try expression (§6.22) which handles the thrown exception, evaluation resumes with the handler; otherwise the thread executing the throw is aborted . The type of a throw expression is scala.Nothing .

throw 式 throw e は、式 e を評価します。 この式の型は Throwable に適合しなくてはなりません。 もし e が例外参照へ評価されるなら、評価は送出される例外でアボートされます。 もし e が null へ評価されるなら、評価は代わりに、NullPointerException でアボートされます。 もし送出された例外を処理するアクティブな try 式 (§6.22)があるなら、 評価はハンドラでレジュームします。; そうでなければ、throw を実行するスレッドはアボートされます。 throw 式の型は scala.Nothing です。



6.22 try 式 (Try Expressions)

構文:

   Expr1     ::=  'try' '{' Block '}' ['catch' '{' CaseClauses '}']
                  ['finally' Expr]

A try expression is of the form try { b } catch h , where the handler h is a pattern matching anonymous function (§8.5)

try 式は try { b } catch h の形です。ここで、 ハンドラ h は次のパターンマッチング無名関数です (§8.5)。

   { case p1 => b1 ... case pn => bn } .

This expression is evaluated by evaluating the block b . If evaluation of b does not cause an exception to be thrown, the result of b is returned . Otherwise the handler h is applied to the thrown exception . If the handler contains a case matching the thrown exception, the first such case is invoked . If the handler contains no case matching the thrown exception, the exception is re-thrown .

この式は、ブロック b の評価に基づいて評価されます。 もし b の評価が例外送出を引き起こさなければ、b の結果が返されます。 そうでなければ、ハンドラ h が送出された例外に適用されます。 もしハンドラが送出された例外にマッチするケースを含むなら、 そのような最初のケースが呼び出されます。 もしハンドラが、送出された例外に対応するケースを含まないなら、 その例外は再送出されます。

Let pt be the expected type of the try expression. The block b is expected to conform to pt. The handler h is expected conform to type scala.PartialFunction[scala.Throwable, pt]. The type of the try expression is the weak least upper bound (§3.5.3) of the type of b and the result type of h .

pt を try 式の要請型であるとします。 ブロック b は pt に適合することが要請されます。 ハンドラ h は、型 scala.PartialFunction[scala.Throwable,pt] に適合することが要請されます。 try 式の型は、b の型と h の結果型の弱い最少の上限境界 (§3.5.3)です。

A try expression try { b } finally e evaluates the block b . If evaluation of b does not cause an exception to be thrown, the expression e is evaluated . If an exception is thrown during evaluation of e, the evaluation of the try expression is aborted with the thrown exception . If no exception is thrown during evaluation of e, the result of b is returned as the result of the try expression .

try 式 try { b } finally e は、ブロック b を評価します。 もし b の評価が例外送出を引き起こさないなら、式 e が評価されます。 もし e の評価中に例外が送出されるなら、try 式の評価は送出される例外で アボートされます。 もし e の評価中に例外が送出されないなら、b の結果が try 式の結果として 返されます。

If an exception is thrown during evaluation of b, the finally block e is also evaluated . If another exception e is thrown during evaluation of e, evaluation of the try expression is aborted with the thrown exception . If no exception is thrown during evaluation of e, the original exception thrown in b is re-thrown once evaluation of e has completed . The block b is expected to conform to the expected type of the try expression . The finally expression e is expected to conform to type Unit .

もし b の評価中に例外が送出されるなら、finally ブロック e も評価されます。 もし e の評価中に他の例外 e が送出されたなら、 try 式の評価は送出される例外でアボートされます。 もし e の評価中に例外が送出されないなら、b 中で送出されたオリジナルの例外が、 e の評価完了後すぐに再送出されます。 ブロック b は、try 式の要請型に適合することが要請されます。 finally 式 e は、型 Unit に適合することが要請されます。

try 式 try { b } catch e1 finally e2 は、 try { try { b } catch e1 } finally e2 の略記表現です。



6.23 無名関数 (Anonymous Functions)

構文:

   Expr         ::=   (Bindings | ['implicit'] id | '_') '=>' Expr
   ResultExpr   ::=   (Bindings | (id | '_') ':' CompoundType) '=>' Block
   Bindings     ::=   '(' Binding {',' Binding} ')'
   Binding      ::=   (id | '_') [':' Type]

The anonymous function (x1 : T1,...,xn : Tn) => e maps parameters xi of types Ti to a result given by expression e . The scope of each formal parameter xi is e . Formal parameters must have pairwise distinct names .

無名関数 (x1 : T1,...,xn:Tn) => e は、 型 Ti のパラメータ xi を式 e によって与えられる結果へマップします。 各形式上のパラメータ xi のスコープは e です。形式上のパラメータは、 対として異なる名前でなくてはなりません。

If the expected type of the anonymous function is of the form scala.Functionn[S1,...,Sn , R], the expected type of e is R and the type Ti of any of the parameters xi can be omitted, in which case Ti = Si is assumed . If the expected type of the anonymous function is some other type, all formal parameter types must be explicitly given, and the expected type of e is undefined . The type of the anonymous function is scala.Functionn[S1,...,Sn , T], where T is the packed type (§6.1) of e . T must be equivalent to a type which does not refer to any of the formal parameters xi .

The anonymous function is evaluated as the instance creation expression

もし無名関数の要請型が scala.Functionn[S1,...,Sn,R] の形なら、 e の要請型は R であり、そしていずれのパラメータ xi の型 Ti も省略でき、 その場合、Ti = Si が想定されます。 もし無名関数の要請型が他のある型なら、 すべての形式上のパラメータ型は明示的に与えられなければならず、 e の要請型は未定義となります。 無名関数の型は scala.Functionn[S1,...,Sn,T] であり、 ここで T は e のパックされた型 (§6.1)です。 T は形式上のパラメータ xi のいずれをも参照しない型に等価でなければなりません。

無名関数は、次のインスタンス生成式として評価されます。

   new scala.Functionn[T1,...,Tn , T] {
     def apply(x1 : T1,...,xn : Tn): T = e
   }

In the case of a single untyped formal parameter, (x) => e can be abbreviated to x => e . If an anonymous function (x : T) => e with a single typed parameter appears as the result expression of a block, it can be abbreviated to x : T => e .

ただ 1 つの 型付けされていない形式上のパラメータについては、(x) => e を x => e と短く書けます。 もしただ 1 つの型付けされたパラメータをもつ無名関数 (x : T) => e が、 ブロックの結果式として現われるなら、これを x : T => e と短く書けます。

A formal parameter may also be a wildcard represented by an underscore _. In that case, a fresh name for the parameter is chosen arbitrarily .

形式上のパラメータは、下線 _ で表されるワイルドカードでも構いません。 そのような場合、パラメータのために新規の名前が勝手に選択されます。

A named parameter of an anonymous function may be optionally preceded by an implicit modifier . In that case the parameter is labeled implicit (§7); however the parameter section itself does not count as an implicit parameter section in the sense of (§7.2). Hence, arguments to anonymous functions always have to be given explicitly .

無名関数の名前付きパラメータに、オプションとして implicit 修飾子が先行するかもしれません。 そのような場合、パラメータは implicit と印されます (§7)。; しかし、パラメータ部それ自身は、 (§7.2) の意味での暗黙のパラメータ部としては扱われません。 ですから、無名関数への引数は常に明示的に与えられなければなりません。


Example 6.23.1 無名関数の例:

   x => x                       // 同じ値の関数 (The identity function)
 
   f => g => x => f(g(x))       // カリー化された関数合成
                                // Curried function composition
 
   (x: Int,y: Int) => x + y     // 和の関数
 
   () => { count += 1; count }  //  空きのパラメータリスト ()をとり
                                //  非ローカルな変数 'count'を
                                //  インクリメントし、新しい値を返す。
 
   _ => 5                       // 引数を無視する関数。常に 5 を返す。
                                // 


無名関数のためのプレースホルダー構文 (placeholder syntax for anonymous functions)

構文:

   SimpleExpr1     ::=   '_'

An expression (of syntactic category Expr) may contain embedded underscore symbols _ at places where identifiers are legal . Such an expression represents an anonymous function where subsequent occurrences of underscores denote successive parameters .

式(構文カテゴリ Expr)には、識別子があってよい場所に、下線シンボル _ が 埋め込まれているかもしれません。 そのような式は、それに続く下線の出現が一連のパラメータを表す、 無名関数を表します。

Define an underscore section to be an expression of the form _:T , where T is a type, or else of the form _, provided the underscore does not appear as the expression part of a type ascription _:T .

下線部 を _:T の形 (ここで T は型)、 あるいはそうでなければ _ の形の式で定義してください。 ただしここで、下線は型帰属(type ascription) _:T の式部分として現われる のではないとします。

An expression e of syntactic category Expr binds an underscore section u, if the following two conditions hold: (1) e properly contains u, and (2) there is no other expression of syntactic category Expr which is properly contained in e and which itself properly contains u .

もし次の 2 つの条件が満たされるなら、構文カテゴリ Expr の式 e は下線部 u を 束縛します 。: (1) e が適切に u を含む。そして (2) e に適切に含まれ、それ自身適切に u を含む構文カテゴリ Expr の式が他にない。

If an expression e binds underscore sections u1,...,un , in this order, it is equivalent to the anonymous function (u´1 , ... u´n) => e´ , where each u´i results from ui by replacing the underscore with a fresh identifier and e´ results from e by replacing each underscore section ui by u´i .

もし式 e が、下線部 u1,...,un をこの順で束縛するなら、それは無名関数 (u´1、...u´n) => e´に等価です。 ここで、各 u´i は ui の下線部を新規の識別子で置き換えたもの、 e´ は e の各下線部 ui を u´i で置き換えたものとします。


Example 6.23.2 左カラム中の無名関数は、プレースホルダー構文を使っています。 それぞれ、右側の無名関数に等価です。

   _ + 1                   x => x + 1
   _ * _                   (x1, x2) => x1 * x2
   (_: Int) * 2            (x: Int) => (x: Int) * 2
   if (_) x else y         z => if (z) x else y
   _.map(f)                x => x.map(f)
   _.map(_ + 1)            x => x.map(y => y + 1)



6.24 定数式 (Constant Expressions)

Constant expressions are expressions that the Scala compiler can evaluate to a constant . The definition of "constant expression" depends on the platform, but they include at least the expressions of the following forms:

定数式は Scala コンパイラが定数へ評価できる式です。 「定数式」の定義はプラットフォームに依存します。 しかし、少なくとも次の形の式があります。:

  • A literal of a value class, such as an integer
  • A string literal
  • A class constructed with Predef.classOf (§12.5)
  • An element of an enumeration from the underlying platform
  • A literal array, of the form Array(c1,...,cn), where all of the ci 's are themselves constant expressions
  • An identifier defined by a constant value definition (§4.1) .
  • 値クラスのリテラル。例としては 1 つの整数。
  • 文字列リテラル。
  • Predef.classOf (§12.5) で構築されるクラス。
  • 基盤となっているプラットフォームからの列挙要素。
  • Array(c1,...,cn) の形のリテラル配列。ここで ci はすべてそれ自身が定数式。
  • 定数値定義(§4.1) によって定義された識別子。



6.25 文 (Statements)

構文:

   BlockStat    ::=        Import
                  |        {Annotation} ['implicit'] Def
                  |        {Annotation} {LocalModifier} TmplDef
                  |        Expr1
                  |
   TemplateStat ::=        Import
                  |        {Annotation} {Modifier} Def
                  |        {Annotation} {Modifier} Dcl
                  |        Expr
                  |

Statements occur as parts of blocks and templates . A statement can be an import, a definition or an expression, or it can be empty . Statements used in the template of a class definition can also be declarations . An expression that is used as a statement can have an arbitrary value type . An expression statement e is evaluated by evaluating e and discarding the result of the evaluation .

文はブロックおよびテンプレートの一部として現れます。 文はインポート、定義あるいは式、あるいは空でも構いません。 クラス定義のテンプレート中で使われる文は、宣言であることもあります。 文として使われる式は、任意の値型を持てます。 式の文 e は、e を評価し評価結果を捨てることで、評価されます。

Block statements may be definitions which bind local names in the block . The only modifier allowed in all block-local definitions is implicit . When prefixing a class or object definition, modifiers abstract, final, and sealed are also permitted .

Evaluation of a statement sequence entails evaluation of the statements in the order they are written .

ブロックの文は、ブロック内のローカルな名前を束縛する定義でも構いません。 ブロックにローカルなあらゆる定義中で許される唯一の修飾子は、implict です。 クラス/オブジェクト定義に前置するものとしては、修飾子 abstract、 final と sealed も許されます。

文並びの評価は、それらが書かれた順で評価されます。

タグ:

+ タグ編集
  • タグ:

このサイトはreCAPTCHAによって保護されており、Googleの プライバシーポリシー利用規約 が適用されます。

最終更新:2011年02月23日 18:36
ツールボックス

下から選んでください:

新しいページを作成する
ヘルプ / FAQ もご覧ください。