LoginSignup
1
3

More than 5 years have passed since last update.

Scalaの制御構文(1)

Posted at

はじめに

下記のテキストを通して、基本的な書き方を学びつつ、個人的に気になったことを検証していくメモ代わりです。
https://dwango.github.io/scala_text/basic.html
本当にありがとう、dwango様・・・

Scalaの制御構文

ざっくりまとめ

  • 「構文」と「式」と「文」それぞれ使い分けよう
  • {} 式は基本中の基本
  • if式、whileはCやPHPと同様の使用感
  • for分はifを中にぶっこめたり、yieldにより四季を生成できる

「構文」と「式」と「文」という用語

(今まで気にしていなかった)各種用語にかんして、ざっくりまとめ

  • 構文(Syntax)
    • プログラミング言語内で特別扱いされるキーワードと正しいプログラムを構成するためのルール
  • 式(Expression)
    • 評価することで値になるもの
    • 1 , 1 + 2 , "hoge"
  • 文(Statement)
    • 評価しても値にならないもの(定義全体としては値を持たないもの)
    • val i:Int = 1

{}

  • 一般系

    { exp1; exp2; ... expN }
    
    • 式が改行で区切られていれば セミコロンを省略可
  • Scalaではメソッド定義が一般的

    def foo(): String = {
        "foo" + "foo"
    }
    
    • メソッド定義の構文に特別に {} が含まれているわけではない
      • {"foo" + "foo"} という式が、メソッドに代入されているってことかな? ## if式
  • 一般式

    if (条件式) A [else B]
    
  • 使用方法

    scala> var age = 26
    age: Int = 26
    
    scala> if (age < 20) {
     |     "未成年"
     | } else {
     |     "年がどんどん・・・"
     | }
    res1: String = 年がどんどん・・・
    
    scala> if (age < 20) {}
    
    

while式

  • 一般式

    while (条件式) A
    
  • 使用方法

    scala> var i = 1
    i: Int = 1
    
    scala> while (i <= 10) {
         |     print( i + ", ")
         |     i++
         | }
    <console>:11: error: value ++ is not a member of Int
                      i++
                       ^
    
    scala> while (i <= 10) {
         |     print( i + ", ")
         |     i += 1
         | }
    1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
    
    • インクリメント演算子が使えないんだという発見w

for式

  • 一般式

    for(ジェネレータ1;  ジェネレータ2; ... ジェネレータn) A
    # ジェネレータ1 = a1 <- exp1; ジェネレータ2 = a2 <- exp2; ... ジェネレータn = an <- expn
    
  • 使用方法

    • 通常

      scala> for (x <- 1 to 5; y <- 1 until 5) {
       |     print( "(" + x + "," + y + ") ")
       | }
      (1,1) (1,2) (1,3) (1,4) (2,1) (2,2) (2,3) (2,4) (3,1) (3,2) (3,3) (3,4) (4,1) (4,2) (4,3) (4,4) (5,1) (5,2) (5,3) (5,4)
      
      • 前述したジェネレータが内部にネストしたループのように扱われる
        • 多重ループ書く時にネストが深くならなくて使いやすそうと思った
    • if有りの使用方法

      scala> for (x <- 1 to 5; y <- 1 until 5 if x != y) {
           |     print( "(" + x + "," + y + ") ")
           | }
      (1,2) (1,3) (1,4) (2,1) (2,3) (2,4) (3,1) (3,2) (3,4) (4,1) (4,2) (4,3) (5,1) (5,2) (5,3) (5,4)
      
      • 条件式も後述できる
    • ifが中間のジェネレータの場合

      scala> for (x <- 1 to 5; y <- 1 until 5 if x != y; z <- 3 to 8) {
           |     print( "(" + x + "," + y + "," + z +") ")
           | }
      (1,2,3) (1,2,4) (1,2,5) (1,2,6) (1,2,7) (1,2,8) (1,3,3) (1,3,4) (1,3,5) (1,3,6) (1,3,7) (1,3,8) (1,4,3) (1,4,4) (1,4,5) (1,4,6) (1,4,7) (1,4,8) (2,1,3) (2,1,4) (2,1,5) (2,1,6) (2,1,7) (2,1,8) (2,3,3) (2,3,4) (2,3,5) (2,3,6) (2,3,7) (2,3,8) (2,4,3) (2,4,4) (2,4,5) (2,4,6) (2,4,7) (2,4,8) (3,1,3) (3,1,4) (3,1,5) (3,1,6) (3,1,7) (3,1,8) (3,2,3) (3,2,4) (3,2,5) (3,2,6) (3,2,7) (3,2,8) (3,4,3) (3,4,4) (3,4,5) (3,4,6) (3,4,7) (3,4,8) (4,1,3) (4,1,4) (4,1,5) (4,1,6) (4,1,7) (4,1,8) (4,2,3) (4,2,4) (4,2,5) (4,2,6) (4,2,7) (4,2,8) (4,3,3) (4,3,4) (4,3,5) (4,3,6) (4,3,7) (4,3,8) (5,1,3) (5,1,4) (5,1,5) (5,1,6) (5,1,7) (5,1,8) (5,2,3) (5,2,4) (5,2,5) (5,2,6) (5,2,7) (5,2,8) (5,3,3) (5,3,4) (5,3,5) (5,3,6) (5,3,7) (5,3,8) (5,4,3) (5,4,4) (5,4,5) (5,4,6) (5,4,7) (5,4,8)
      
      • 記述可能
    • 定義されてなくて、きっとだめだろうと思うやつ

      scala> for (x <- 1 to 5 if x != y; y <- 1 until 5; z <- 3 to 8) {
           |     print( "(" + x + "," + y + "," + z +") ")
           | }
      <console>:8: error: not found: value y
                    for (x <- 1 to 5 if x != y; y <- 1 until 5; z <- 3 to 8) {
                                             ^
      
      • ですよね
    • Listを使用した出力

      scala> for(e <- List("A", "B", "C", "D", "E")) println(e)
      A
      B
      C
      D
      E
      
      scala> for(e <- List("A", "B", "C", "D", "E")) print(e + ", ")
      A, B, C, D, E,
      
    • yieldを使用

      scala> for(e <- List("A", "B", "C", "D", "E")) yield {
           |   "Pre" + e
           | }
      res8: List[String] = List(PreA, PreB, PreC, PreD, PreE)
      
      • yield:産する、もたらす、生む、引き起こす
      • コレクションの要素を加工して返す(新規に生成してくれるやつ)
    • 数値の場合はどうなる?

      scala> for (x <- 1 to 5; y <- 1 until 5) yield {
           |     x + "," + y
           | }
      res9: scala.collection.immutable.IndexedSeq[String] = Vector(1,1, 1,2, 1,3, 1,4, 2,1, 2,2, 2,3, 2,4, 3,1, 3,2, 3,3, 3,4, 4,1, 4,2, 4,3, 4,4, 5,1, 5,2, 5,3, 5,4)
      
      scala> for (x <- 1 to 5; y <- 1 until 5) yield {
           |     x + y
           | }
      res10: scala.collection.immutable.IndexedSeq[Int] = Vector(2, 3, 4, 5, 3, 4, 5, 6, 4, 5, 6, 7, 5, 6, 7, 8, 6, 7, 8, 9)
      
      • 普遍のcollectionで返してくれる
      • 型は自動生成される
      • でも、vectorだから、自分で定義できないのかな?
        • 調査した感じ、ジェネレータの型で自動で変換するらしいので、型はジェネレータで指定が無難?
    • とりあえず、ジェネレータで色々試す

      scala> for (x <- List(1 to 5); y <- 1 until 5) yield {
           |     x + y
           | }
      <console>:9: error: type mismatch;
       found   : Int
       required: String
                        x + y
                            ^
      
      scala> for (x <- List(1 to 5); y <- List(1 until 5)) yield {
           |     x + y
           | }
      <console>:9: error: type mismatch;
       found   : scala.collection.immutable.Range
       required: String
                        x + y
                            ^
      
      scala> for (x <- List(1 to 5); y <- List(1 to 5)) yield {
           |     x + y
           | }
      <console>:9: error: type mismatch;
       found   : scala.collection.immutable.Range.Inclusive
       required: String
                        x + y
                            ^
      scala> for (x <- List(1 to 5); y <- List(1 to 5)) yield {
           |     x + "," + y
           | }
      res15: List[String] = List(Range(1, 2, 3, 4, 5),Range(1, 2, 3, 4, 5))
      
      scala> for (x <- List(1,2,3); y <- List(4,5,6)) yield {
           |     x + y
           | }
      res16: List[Int] = List(5, 6, 7, 6, 7, 8, 7, 8, 9)
      
      scala> for (x <- List(1,2,3); y <- List(4,5,6)) yield {
           |     x + "," + y
           | }
      res17: List[String] = List(1,4, 1,5, 1,6, 2,4, 2,5, 2,6, 3,4, 3,5, 3,6)
      
      • toやuntilを使用すると、Range型になるので、直接的な結合は変換後じゃないと難しそう
        • 今後、型変換に関して学んだ上で追記したいところ
1
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
3