Scala学習(二)

3817 ワード

Scalaのいくつかの高度な特性
高次関数
通常、パラメータとしてメソッドに渡すことができる式を関数と呼びます.関数式プログラミング言語では、関数は「ファースト公民」であり、高次関数には値としての関数、匿名関数、閉パッケージ、コリー化などが含まれている.
  • は、値の関数&匿名関数として、他のデータ型のように伝達および操作される関数であり、アルゴリズムに特定の動作を伝達するたびに、この特性が非常に役立ちます.
  • val arr = Array(1, 2, 3, 4, 5)
    val f1 = (x: Int) => x * 2
    //      
    val arr1: Array[Int] = arr.map(f1)
    
    //    
    val arr2: Array[Int] = arr.map((x: Int) => x * 2)
    //      
    val arr3: Array[Int] = arr.map(_ * 2)
    
  • コリー化コリー化(Currying)とは、複数のパラメータを受け入れた関数を1つのパラメータを受け入れる関数に変換するプロセスであり、残りのパラメータを受け入れ、結果を新しい関数に返すことを意味する.

  • scalaコリー化スタイルの使用は主関数の複雑さを簡略化し、主関数の自閉性を高め、機能上の拡張性、柔軟性を高めることができる.より抽象的で機能的で効率的な関数コードを記述することができます.
    //        
    //def m1(x: Int) = (y: Int) => x + y
    def m1(x: Int)(y: Int) = x + y
    //          
    val i: Int = m1(1)(2)
    
    //      m1(1)(2)        
    //               (                     )
    val f1: Int => Int = m1(1)
    //              
    val i1: Int = f1(2)
    
  • 閉パケット閉パケットは、関数の外部に宣言された1つ以上の変数に依存する関数の戻り値である.一般的には、現在の役割ドメインの範囲内ではない関数にアクセスできると簡単に考えられます.
  • val y = 2
    //  y          ,            
    // add      :x y。x        ,y       
    val add = (x: Int) => x + y
    
    println(add(1)) //3
    

    暗黙的変換と暗黙的パラメータ
  • ステルス変換Scalaが提供するステルス変換とステルスパラメータ機能は、非常に特色のある機能です.Javaなどのプログラミング言語にはない機能です.手動で指定したり、あるタイプのオブジェクトを他のタイプのオブジェクトに変換したり、クラスにメソッドを追加したりすることができます.これらの機能により、非常に強力で特殊な機能を実現できます.Scalaの暗黙的な変換は、最も核心的な暗黙的な変換方法、すなわちimplicit conversion functionを定義することである.定義された暗黙的な変換方法は,作成されたプログラム内に導入されるとScalaによって自動的に使用される.Scalaは、暗黙変換メソッドの署名に基づいて、プログラムで暗黙変換メソッドが受信したパラメータタイプ定義のオブジェクトを使用すると、自動的に暗黙変換メソッドに転送され、別のタイプのオブジェクトに変換されて返されます.これが「暗黙的変換」です.ここで、すべての暗黙値と暗黙メソッドをobjectに配置する必要があります.しかし、Scalaを使用する暗黙的な変換には一定の制限があり、以下にまとめる.
  • implicitキーワードは、メソッド、変数(パラメータ)を修飾するためにのみ使用できます.
  • 暗黙的に変換する方法は、現在の範囲内でのみ有効です.暗黙的な変換が現在の範囲内で定義されていない場合(たとえば、別のクラスに定義されているか、オブジェクトに含まれているなど)、import文で導く必要があります.

  • 暗黙パラメータ暗黙パラメータとは、関数またはメソッドでimplicitで修飾されたパラメータを定義することを意味し、Scalaは指定されたタイプのimplicitで修飾されたパラメータ、すなわち暗黙値を見つけ、パラメータを注入しようと試みる.Scalaは2つの範囲で検索されます.
  • 現在の役割ドメイン内に表示されるvalまたはvar定義の暗黙変数.
  • 暗黙パラメータタイプの伴生オブジェクト内の暗黙値である.

  • 暗黙変換メソッドの役割ドメインとインポート(1)Scalaのデフォルトでは、ソースタイプ、またはターゲットタイプの伴生オブジェクト内の暗黙変換メソッドの2つの暗黙変換が使用されます.1つは、現在のプログラムの役割ドメイン内の一意の識別子で表すことができる暗黙的な変換方法である.(2)暗黙変換方法が上記の2つの場合でない場合、import test._のようなパケット下の暗黙変換方法を手動でimport構文を用いて導入する必要がある.通常、暗黙的な変換が必要な場合にのみ、importで暗黙的な変換方法を導入することを推奨します.これにより、暗黙的な変換方法の役割ドメインを縮小し、不要な暗黙的な変換を回避することができます.
  • 暗黙変換のタイミング(1)オブジェクト呼び出しクラスに存在しないメソッドまたはメンバーの場合、コンパイラはオブジェクトを自動的に暗黙変換する(2)メソッドのパラメータのタイプがターゲットタイプと一致しない場合
  • .
    暗黙的変換:FileクラスにRichFileクラスのreadメソッドを持たせる
    import java.io.File
    import scala.io.Source
    
    object MyPredef{
      //        
      implicit def file2RichFile(file: File)=new RichFile(file)
    }
    class RichFile(val f:File) {
      def read()=Source.fromFile(f).mkString
    }
    object RichFile{
      def main(args: Array[String]) {
        val f=new File("D://words.txt")
        //  import        
        //import MyPredef._
        import MyPredef.file2RichFile
        //      , File    RichFile     
        val content=f.read()
        println(content)
      }
    }
    

    1つのクラスが同じメソッドを持つ複数のクラスに暗黙的に変換された場合、インポート時に1つしかインポートできません.そうしないと、共通メソッドが呼び出されたときにコードエラーが発生します.
    暗黙パラメータ:暗黙値を定義するときに同じタイプの暗黙値を1回だけ許可します.そうしないと、エラーが発生します.
    object Value {
      // object      ;               ,     !
      implicit val aaa = "zhangsan"
      implicit val bbb = 18
    }
    
    class Person {
      //  implicit    
      //          String      
      def getName()(implicit name: String): String = {
        "  :" + name
      }
    
      //          Double      
      def getAge()(implicit age: Int): String = {
        "  :" + age
      }
    }
    
    object Person extends App {
      //  import         ,          
      import Value._
    
      val p = new Person
      println(p.getName() + p.getAge())
    }