scalaこれは何を書いていますか?1編の文章で暗黙的な転換を明らかにする

5192 ワード

目次
  • 前言
  • 通常の問題:暗黙的な変換は何ですか
  • 暗黙的な変換の実現方法
  • クイックエントリー
  • 強力な拡張機能
  • 暗黙的な変換
  • 暗黙的方法
  • 暗黙値
  • 暗黙クラス
  • 最後の
  • 前言
    scalaは簡潔さで有名で、どのように簡単にどのように来るか知っています.scalaの簡潔な文法については、よく知っている人はscalaを爱し、よく知らない人はscalaに苦しめられていると広く言われています.scalaという言語に対して、javaに慣れた同級生はよく新しい名詞を聞いて、不思議で神の神秘的で、はい、間違いなく、あなたのことを言っています--暗黙的な転換、隠していて、早く私にあなたの秘密を覗かせてください.
    一般的な質問:暗黙的な変換は何ですか?
    ここでは、暗黙的な変換とは何かはともかく、scalaのタイプ変換を狙って、scalaのByte、Short、Int、Longのタイプについて、Byte->Short->Int->Longのように変換すれば、scalaは自動的に実現してくれます.それ以外に、サブクラス->親クラス->特質などのマルチステート構文のタイプ変換もよく見られます.これらはscalaがデフォルトでサポートしている自動タイプ変換であり、暗黙的な変換の一種ですが、ここまで言うだけで終わったら、scalaも学ぶことはありません.
    以上述べた自動変換は,継承関係や精度の関係など,関係を持つ.1つのケースを考慮すると、2つの無関係タイプで変換したい場合、scalaでの暗黙的な変換は実現できますか.
    これには、暗黙的な変換を実現するために変換ルールをカスタマイズする必要があります.
    暗黙的な変換の方法
    私たちがカスタマイズした暗黙変換は、implicitキーワードで宣言された単一のパラメータを持つ関数である暗黙変換関数という関数実装が必要です.この関数は自動的に適用され、値を1つのタイプから別のタイプに変換します.
    クイックスタート
    show me the code:
      def main(args: Array[String]): Unit = {
        // implicit        
        implicit def transform(d:Double):Int={
          d.toInt
        }
    
        val i:Int = 5.0
    
        println(i)
      }
    

    implicitキーワード修飾の関数は暗黙関数です.この例では、まずiを見て、タイプはIntタイプとして定義されていますが、付与値5.0は、ここではタイプが異なります.コンパイラは、この2つのタイプを自動的に変換できないときに、カスタム変換ルールを検索します.つまり、implicitキーワードを検索すると、暗黙変換関数のタイプが適切に一致していることがわかります.そこで暗黙的に変換した.
    パラメータのタイプや戻り値のタイプを変更すると、変換は成功しますか?
    	def main(args: Array[String]): Unit = {
      	//     Int  Float
        implicit def transform(d:Double):Float={
          d.toInt
        }
    
        val i:Int = 5.0
        println(i)
      }
    

    実行すると、変換が実現できず、コンパイラがエラーを報告することがわかります.
     type mismatch;
     found   : Double(5.0)
     required: Int
        val i:Int = 5.0
    

    パラメータ名とパラメータタイプを変更する例は、自分で試してみてください.
    上記の例から、暗黙変換関数の関数名は任意であってもよく、暗黙変換は関数のパラメータタイプと戻り値タイプにのみ関係し、関数名には関係しない.
    次に、2つの暗黙関数を連続的に書くと、パラメータと戻り値のタイプが同じで、関数名が異なる場合はどうなりますか.
    	def main(args: Array[String]): Unit = {
        implicit def transform(d:Double):Int={
          d.toInt
        }
    
        implicit def transform1(d:Double):Int={
          d.toInt
        }
    
        val i:Int = 5.0
    
        println(i)
      }
    

    実行すると、次のエラーが発生します.
    Note that implicit conversions are not applicable because they are ambiguous:
     both method transform1 of type (d: Double)Int
     and method transform of type (d: Double)Int
     are possible conversion functions from Double(5.0) to Int
        val i:Int = 5.0
    

    ここには同じ役割を果たすプライバシー変換関数が複数あり,コンパイラはどれが適切か判断できない.したがって、暗黙関数は複数あり得るが、同じ役割ドメインには同じタイプの変換規則が複数存在しないことを保証しなければならない.
    まとめ:
  • 暗黙変換関数はimplicitキーワードで宣言された単一パラメータ付き関数
  • である.
  • 暗黙変換は、関数のパラメータタイプと戻り値タイプにのみ関係し、関数名に関係なく
  • 同じ役割ドメインに同じタイプの変換規則が複数あることはできない
  • .
    強力な拡張機能
    現在のプログラムでは、既存のクラスに新しいメソッドを追加するのは簡単ですが、実際のプロジェクトでは、新しいメソッドを追加するにはソースコードを変更する必要があり、ソースコードを変更するとOCP開閉の原則に反する可能性があります.これは受け入れにくいので、この場合、暗黙的に関数を変換してクラスに動的に機能を追加することができます.
    やはり栗を乾かす代わりに持ってきてください.
    今、私たちはMysqlのクラスを開発しました.中にはselectメソッドしか含まれていません.これはコードライブラリに提出されています.どんな理由があっても、Mysqlクラスのソースコードを修正することはできません.
    class Mysql {
      def select(): Unit = {
        //         
      }
    }
    
      def main(args: Array[String]): Unit = {
        val mysql = new Mysql()
        mysql.select()
      }
    

    その後の需要反復ではmysqlにdeleteメソッドを追加する必要がありますが、ソースコードを変更することはできません.暗黙的に拡張機能に変換できます.
    class Operater {
      def delete(): Unit = {
    		//         
      }
    }
    
      def main(args: Array[String]): Unit = {
    
        val mysql = new Mysql()
        mysql.select()
    
        implicit def transfrom(mysql: Mysql): Operater = {
          new Operater()
        }
    
        mysql.delete()
      }
    

    暗黙的な変換
    暗黙の方法
    上記の入門例、すなわち暗黙的な方法については、ここでは後述しない.
    暗黙の値
    暗黙値は暗黙変数とも呼ばれ、あるパラメータをimplicitとマークし、コンパイラはメソッド呼び出しでパラメータを省略した場合に、役割ドメイン内の暗黙値をデフォルトパラメータとして検索します.ツッコミを入れなければならない.この言葉はめちゃくちゃだが、仕方がない.scalaという文法は少し乱れている.
    適用例:
    	def main(args: Array[String]): Unit = {
        implicit val nameTr:String = "  "
      
        def function(implicit name:String):Unit={
          println(name)
        }
      
        function("  ")
        function
      }
    

    出力:
      
      
    

    定義に従って説明すると、scalaはメソッド呼び出しパラメータを使用し、メソッド呼び出しパラメータがない場合、scalaは暗黙的変換を使用し、nameTrをnameに変換する.変換を実現するには、nameTrとnameのタイプが一致しなければならないことに注意してください.
    暗黙クラス
    scala 2.0の後に暗黙的なクラスが提供され、implict宣言クラスを使用することができ、暗黙的なクラスは同様にクラスの機能を拡張することができ、前に暗黙的な方法を使用して豊富なクラスライブラリ機能を変換するよりも便利である.
    暗黙的なクラスの使用には、次のような特徴があります.
  • クラスのコンストラクション関数は1つしかありません.このパラメータは、変換が必要なオブジェクト
  • です.
  • 暗黙的なクラスは、クラス、伴生オブジェクト、またはパッケージオブジェクトの内部でのみ定義でき、トップクラスの
  • ではありません.
  • 暗黙クラスはcase class
  • ではありません.
    暗黙クラスは暗黙メソッドより豊富なクラスライブラリ機能を変換するのが便利であるため,前のMysqlの例を改造して比較することで,暗黙クラスを1つ定義するだけで機能拡張を実現できる.
    class Mysql {
      def select(): Unit = {
    
      }
    }
    
    	def main(args: Array[String]): Unit = {
        val mysql = new Mysql()
        mysql.select()
    		
        //        ,   Mysql   
        implicit class Operater(mysql1:Mysql) {
          def delete(): Unit = {
          }
        }
    
        mysql.delete()
      }
    

    最後に
    scalaを学ぶのは容易ではありません.この文章は暗黙的な変換の神秘的なベールを明らかにしました.暗黙的な変換の紹介から、使用まで、分類まで、できるだけ通俗的な言語と詳細なdemoのケースではっきり説明して、scalaの暗黙的な変換に慣れていないパートナーに少し助けてほしいと思っています.