【Scala 2.1.8入門】Scala入門④モードマッチング及び異常汎用暗黙変換2019_12_3
24928 ワード
Scala入門④モードマッチング及び異常汎用暗黙変換モードマッチング モードマッチング関数式 定数値一致 範囲マッチング/モードガード 用途要約 字面量・値マッチング 変数タイプ一致 Array精密整合 List精確一致 Array/List集合におけるメタセットマッチング オブジェクト/サンプルクラス一致 サンプルクラスマッチング 変数受信マッチング forループ変数受信マッチング バイアス関数 暗黙変換 暗黙関数 暗黙クラス 暗黙パラメータ 暗黙解析機構 異常 汎用 コヒーレントインバータ 上下限 補足:Java Classオブジェクト取得 汎用マウント 暗黙パラメータ[汎用]は を限定する.
パターンマッチング
Java Switch Case構文に似ていますが、Scala Match Caseの機能はより強力で、コード貫通の問題はありません.
最も重要なことは、パターンマッチング自体が関数であり、通常は「x=>x match{case}」を「」と省略してキーワードのない匿名関数形式であり、Tupleメタグループ形式では「{case(t 1,t 2)=>...」と略記されるcaseを明記しないと、(t 1,t 2)のタイプ推定ができず、1つのメタグループではなく2つのパラメータとして扱われることである.
モードマッチング関数式
定数の一致
範囲一致/モードガード
定数値マッチングは、範囲マッチングの特殊な形式であり、範囲マッチングフォーマットを簡略化していることが理解できます.
用途要約
**ポイント:**case順!!現在のcaseを満たすことはできません!!!注意類似マッチング範囲のcaseは範囲が小さい->大きい順に配列されている.
字面量・値マッチング
変数タイプの一致
特殊:汎用消去
Array精密整合
List精確マッチング
方式1:同Array
方式2:独自
Array/Listコレクション内のメタグループマッチング
きそ
拡張
オブジェクト/サンプルクラスの一致
抽出対象の1つの属性は、抽出器がunapply(obj:Obj):Option[T]抽出対象の複数の属性である場合、抽出器がunapply(obj:Obj):Option[(T 1,T 2,T 3...)]抽出対象の可変属性である場合、抽出器がunapplySeq(obj:Obj):Option[Seq[T]]である
サンプルクラスマッチングサンプルクラスは依然としてクラスであり、通常のクラスと比較して、自動的に伴生オブジェクトが生成され、apply、unapply、toString、equals、hashCode、copyなどの伴生オブジェクトで自動的に一般的な方法が実装されるだけである. サンプルクラスは、デフォルトでunapplyメソッドが提供されているため、サンプルクラスは、unapplyメソッドを独自に実装することなく、モードマッチングのために最適化されたクラスである. コンストラクタの各パラメータはvalとなります.varとして明示的に宣言されない限り(推奨されません) です.
変数受信照合
forループ変数受信マッチング
バイアス関数
バイアス関数も関数の一種であり,バイアス関数により入力パラメータのより正確な検査を容易に行うことができる.
まとめ:バイアス関数は,集合内の部分データの処理である.
バイアス関数の定義:
[外部チェーン画像の転送に失敗しました.ソース局には盗難防止チェーンのメカニズムがある可能性があります.画像を保存して直接アップロードすることをお勧めします(img-UohZar 3 E-1575361305616)(iバイアス関数.png)]
バイアス関数の使用方法:
バイアス関数の操作:
暗黙的変換
動作原理とその存在意義:
コンパイラが最初にコンパイルに失敗すると、タイプを変換したり、二次コンパイルを実現したりするなど、コードコンパイルを通過させる方法が現在の環境で検索されます.
実質:簡略化版のJava装飾設計モデルであり、既存のソースコードを変更できないタイプに新しい方法を追加する.
暗黙関数
実質:「構造関数」、外に書かれた構造関数
暗黙クラス
Scala 2.10(現2.13)の後に暗黙クラスが提供され、暗黙関数と同様にimplicitキーワードで修飾されるが、暗黙クラスは暗黙関数に対する超拡張である
暗黙パラメータ
一般的なメソッドまたは関数のパラメータはimplicitキーワードで暗黙的なパラメータとして宣言できます.
暗黙解析メカニズム
異常
汎用型
基本定義構文/汎用テンプレート:class ClassName[T]{}
コヒーレントインバータ
コヒーレント定義:class ClassName[+T](){}
インバータ定義:class ClassName[-T](){}
可変定義:class ClassName[T](){}
上下限
補足:Java Classオブジェクトの取得
汎用マウント
暗黙パラメータ[汎用]定義
コンテキスト限定は、汎用および暗黙的な変換を組み合わせた生成物である.
パターンマッチング
Java Switch Case構文に似ていますが、Scala Match Caseの機能はより強力で、コード貫通の問題はありません.
最も重要なことは、パターンマッチング自体が関数であり、通常は「x=>x match{case}」を「」と省略してキーワードのない匿名関数形式であり、Tupleメタグループ形式では「{case(t 1,t 2)=>...」と略記されるcaseを明記しないと、(t 1,t 2)のタイプ推定ができず、1つのメタグループではなく2つのパラメータとして扱われることである.
モードマッチング関数式
object Test {
def main(args: Array[String]): Unit = {
//
List(1,2,3,4).map(x=>x match {
case 4 => println("Str")
case x:Int => println("Int")
})
//
List(1,2,3,4).map({
case 4 => println("Array")
case x:Int => println("Int")
})
}
}
定数の一致
object Scala01_TestMatch {
/*0.java switch case “ ” , Scala , case
switch(byte|short|int|char|enum(1.5)|String(1.7){case:break; ...; default:;}*/
//1.Scala ,Java Switch IfElse , ,
def main(args: Array[String]): Unit = {
var a = 10
val b = 20
// [switch(var)]
val control = 'd'
//2. : match { case Boolean ( · ) => { } ... case _ => {}}
val result = control match {
// ,
case ('+') => {a += 1; a+b}
case '-' => a - b
// case , case _
case _ => "illegal"
}
println(result)
}
}
範囲一致/モードガード
定数値マッチングは、範囲マッチングの特殊な形式であり、範囲マッチングフォーマットを簡略化していることが理解できます.
object Scala02_TestMatch {
def main(args: Array[String]): Unit = {
println(abs(-8))
}
def abs(num:Int)={
num match {
// ==> :
//case Boolean (if ) => block
case i if i >=0 => i
case j if j <0 => -j
case _ => "illegal"
}
}
}
用途要約
**ポイント:**case順!!現在のcaseを満たすことはできません!!!注意類似マッチング範囲のcaseは範囲が小さい->大きい順に配列されている.
字面量・値マッチング
object Scala03_TestMatch {
def main(args: Array[String]): Unit = {
println(describe(true))
}
/**
* ·
* @param x , , ,
* @return String
*/
def describe (x:Any)= x match {
case 5 => "Int 5"
case "hello" => "String hello"
case true => "Boolean True"
case '+' => "Char +"
case _ => "illegal"
}
}
変数タイプの一致
特殊:汎用消去
object Scala04_TestMatch {
def main(args: Array[String]): Unit = {
//1. ,
println(describe(1))
//1.1 Array , Array(), Array[]
println(describe(Array(1,2,3,4,5)))
println(describe(Array("abc")))
//2. , List , ,
// :
println(describe(List("a","b","c")))
/*
Int
List[]
Array[Int]
Other Type
*/
}
def describe(x:Any)= x match {
case a:Int => "Int"
case b:String => "String"
case c:List[Double] => "List[]"
//case c:List[_] => "List[]" //
case d:Array[Int] => "Array[Int]"
case _ => "Other Type"
}
}
Array精密整合
object Scala05_TestMatch {
def main(args: Array[String]): Unit = {
for(arr "0" //error:constructor cannot be instantiated required String
})*/
val result = arr match {
// 0 [1. ]
case Array(0) => "0"
// 2 [2. + ], x,y
case Array(x:Int, y:Int) => x + "," + y
// 0 [3. ]
case Array(0, _*) => " 0 "
case _ => "something else"
}
println("result = " + result)
}
}
}
List精確マッチング
方式1:同Array
object Scala06_TestMatch {
def main(args: Array[String]): Unit = {
//(0) , List(88) , .
for (list "0"
// List( , '_', Error:unbound placeholder parameter
case List(a) => a
// List
case List(x, y) => x + "," + y
// 0 List
case List(0, _*) => "0 ..."
case _ => "something else"
/*
0
88
1,0
0 ...
something else
*/
}
println(result)
}
}
}
方式2:独自
object Scala06_TestMatch {
def main(args: Array[String]): Unit = {
val list: List[Int] = List(1, 2, 5, 6, 7)
list match {
//1.'::' List
case first :: second :: rest => println(first + "-" + second + "-" + rest)
case _ => println("something else")
}//pln 1-2-List(5, 6, 7)
list match {
//2. , :: List
//3. : List ,'::'
//4. , List
case first :: second :: third :: rest => println(rest)
case _ => println("something else")
}//pln List(6, 7)
}
}
Array/Listコレクション内のメタグループマッチング
きそ
object Scala07_TestMatch {
def main(args: Array[String]): Unit = {
for ( tuple println("0 ...")
// 2 0
case (y,0) => println(s"$y" + " 0")
// 2
case (a,b) => println(s"$a $b")
case _ => println("something else")
}
}
}
}
拡張
def main(args: Array[String]): Unit = {
// 1:
// 1 for(tuple println(a)
//case (a, _*) => println(a) // Case clauses excepted
case _ => println("Illegal")
}
}// plt a b c Illegal
// 2 for(tuple ,
println("--- 2 tuple._1 ---")
for (tuple (t._1,t._2))
// ((,)=>{}) (,) , ,
// ( t => (t._1,t._2))
println(list.map(t => (t._1, t._2 * 2)))
// 2 map{case (word,count)=>(word,count*2)}
// map{} ( match)...
println(
list.map{
case (word,count)=>(word,count*2)
}
)
// 3.1 , (String,(String,count)), count * 2
var list1 = List(("a", ("a", 1)), ("b", ("b", 2)), ("c", ("c", 3)))
println(
list1.map{
case (groupkey,(word,count))=>(word,count*2)
}
)
}
オブジェクト/サンプルクラスの一致
抽出対象の1つの属性は、抽出器がunapply(obj:Obj):Option[T]抽出対象の複数の属性である場合、抽出器がunapply(obj:Obj):Option[(T 1,T 2,T 3...)]抽出対象の可変属性である場合、抽出器がunapplySeq(obj:Obj):Option[Seq[T]]である
object Scala08_TestMatch {
def main(args: Array[String]): Unit = {
// new User() == User() 【apply 】
val user: User = new User("zhangsan", 11)
val result = user match {
//case User("zhangsan", 11) unapply() ,user( user match{}) unapply
//unapply user name age , User("zhangsan", 11)
case User("zhangsan", 11) => "yes"
case _ => "no"
}
println(result)
}
}
class User(val name: String, val age: Int)
object User{
def apply(name: String, age: Int): User = new User(name, age)
/**
* case .unapply ( ) Some, , ; , None 。
* @param user user match { case User( ) }
* @return Some ( user ), null, None
*/
def unapply(user: User): Option[(String, Int)] = {
if (user == null)
None
else
Some(user.name, user.age)
}
}
サンプルクラスマッチング
//
case class User(name: String, age: Int)
object TestMatchUnapply {
def main(args: Array[String]): Unit = {
val user: User = User("zhangsan", 11)
val result = user match {
case User("zhangsan", 11) => "yes"
case _ => "no"
}
println(result)
}
}
変数受信照合
case class Person(name: String, age: Int)
object Scala09_TestMatch {
def main(args: Array[String]): Unit = {
case class Person(name: String, age: Int)
//1.
val (x, y) = (1, 2)
println(s"x=$x,y=$y")
//2.
val Array(first, second, _*) = Array(1, 7, 2, 9)
println(s"first=$first,second=$second")
//3.
val Person(name, age) = Person("zhangsan", 16)
println(s"name=$name,age=$age")
}
}
forループ変数受信マッチング
def main(args: Array[String]): Unit = {
val map = Map("A" -> 1, "B" -> 0, "C" -> 3)
//1. Map , (k,v) tuple
for ((k, v) " + v) //3
}
println("----------------------")
//1.2 1 , value k-v , v 0,
for ((k, 0) " + 0) // B->0
}
println("----------------------")
//1.3 1+for if v == 0
for ((k, v) = 1) {
println(k + " ---> " + v) // A->1 c->33
}
}
バイアス関数
バイアス関数も関数の一種であり,バイアス関数により入力パラメータのより正確な検査を容易に行うことができる.
まとめ:バイアス関数は,集合内の部分データの処理である.
バイアス関数の定義:
// : List
val second: PartialFunction[List[Int], Option[Int]] = {
case x :: y :: _ => Some(y)
}
//
val second = new PartialFunction[List[Int], Option[Int]] {
//
override def isDefinedAt(list: List[Int]): Boolean = list match {
case x :: y :: _ => true
case _ => false
}
//
override def apply(list: List[Int]): Option[Int] = list match {
case x :: y :: _ => Some(y)
}
}
[外部チェーン画像の転送に失敗しました.ソース局には盗難防止チェーンのメカニズムがある可能性があります.画像を保存して直接アップロードすることをお勧めします(img-UohZar 3 E-1575361305616)(iバイアス関数.png)]
バイアス関数の使用方法:
def main(args:Array[String]): Unit = {
val second: PartialFunction[List[Int], Option[Int]] = {
case x :: y :: _ => Some(y)
}
// : second(List(1,2,3)), apply , applyOrElse
second.applyOrElse(List(1,2,3), (_: List[Int]) => None)
}
バイアス関数の操作:
// : List(1,2,3,4,5,6,"test") Int , 。
object Scala10_TestPianFunc {
def main(args: Array[String]): Unit = {
// 1:map.filter
println(List(1, 2, 3, 4, 5, 6, "test").map {
_ match {
case i: Int => i + 1
case s: String => s
}
}.filter(a => a.isInstanceOf[Int]))
// 2:PartitionFunction
//final override def collect[B, That](pf: PartialFunction[A, B])(implicit bf: CanBuildFrom[List[A], B, That]): That
println(List(1, 2, 3, 4, 5, 6, "test").collect { case x: Int => x + 1 })
}
}
暗黙的変換
動作原理とその存在意義:
コンパイラが最初にコンパイルに失敗すると、タイプを変換したり、二次コンパイルを実現したりするなど、コードコンパイルを通過させる方法が現在の環境で検索されます.
実質:簡略化版のJava装飾設計モデルであり、既存のソースコードを変更できないタイプに新しい方法を追加する.
暗黙関数
実質:「構造関数」、外に書かれた構造関数
:implicit def funcName(){}
:
object Scala02_TestImplicit {
// , implicit
// : ( , )
// :" ", ( )
implicit def convert(a: Int) = {
new MyRichInt(a)
}
def main(args: Array[String]): Unit = {
// Int / MyRichInt
// , ,
println(2.myMax(6))
}
}
//
class MyRichInt(val self: Int /* Int*/) {
def myMax(i: Int): Int = {
if (self < i) i else self
}
def myMin(i: Int): Int = {
if (self < i) self else i
}
}
暗黙クラス
Scala 2.10(現2.13)の後に暗黙クラスが提供され、暗黙関数と同様にimplicitキーワードで修飾されるが、暗黙クラスは暗黙関数に対する超拡張である
:
(1)
(2) “ ” “ ” “ ” ,
1: ( )
object Scala04_TestImplicit {
def main(args: Array[String]): Unit = {
println(2.myMax(6))
}
//implicit def convert(){}
/**
*
* @param self
*/
implicit class MyRichInt(val self: Int) {
def myMax(i: Int): Int = {
if (self < i) i else self
}
def myMin(i: Int): Int = {
if (self < i) self else i
}
}
}
2: ( , )
//(2) , 。 ,
object TestTransform extends PersonTrait {
def main(args: Array[String]): Unit = {
//(1)
val teacher = new Teacher()
teacher.eat()
teacher.say()
}
class Teacher {
def eat(): Unit = {
println("eat...")
}
}
}
trait PersonTrait { /* , , */ }
object PersonTrait {
// : Teacher => Person
implicit class Person(user:Teacher) {
def say(): Unit = {
println("say...")
}
}
}
暗黙パラメータ
一般的なメソッドまたは関数のパラメータはimplicitキーワードで暗黙的なパラメータとして宣言できます.
:
1. ,
2. , 。
3. ,
4. ()
:
object Scala03_TestImplicit {
def main(args: Array[String]): Unit = {
//
// : , implicit
// :
implicit var name = "banhua"
sayHi
// sayHH()
}
def sayHi(implicit name:String="zhangshan")={
println("hello:"+name)
}
def sayHH(na:String = "banhua") = {
sayHi(na)
}
}
暗黙解析メカニズム
1. ( 、 、 ),
2. ,
:
異常
import java.io.FileNotFoundException
object Scala01_TestException {
def main(args: Array[String]): Unit = {
//1. Scala , ( ) ( )
//throw FileNotFoundException
try{
var a:Int = 10 / 0
}catch{
//2.Scala case e: Exception,
case e:ArithmeticException=>println(" ")
case e:Exception =>println(" ")
}finally {
println("finally ")
}
//f11()
}
//3. , @throws(classOf[ Exception]),
@throws(classOf[NumberFormatException])
def f11()={
"abc".toInt
}
}
汎用型
基本定義構文/汎用テンプレート:class ClassName[T]{}
コヒーレントインバータ
コヒーレント定義:class ClassName[+T](){}
インバータ定義:class ClassName[-T](){}
可変定義:class ClassName[T](){}
// :T,+T,-T
class Student[-T] {}
class Parent {}
class Child extends Parent {}
class SubChild extends Child {}
object Test {
def main(args: Array[String]): Unit = {
//1.[T] : =
val stu11:Student[Child] = new Student[Child]
// Error: Require Child,but now is Parent / SubChild
//val stu12:Student[Child] = new Student[Parent]
//val stu13:Student[Child] = new Student[SubChild]
//2.[+T] : , +++
val stu21: Student[Child] = new Student[Child]
// Error: Require Child,but now is Parent
//val stu22: Student[Child] = new Student[Parent]
val stu23: Student[Child] = new Student[SubChild]
//3.[-T] : , ---
val stu31: Student[Child] = new Student[Child]
val stu32: Student[Child] = new Student[Parent]
// Error: Require Child,but now is SubChild
//val stu33: Student[Child] = new Student[SubChild]
}
}
上下限
//1.Java
class Student {}
class Parent {}
class Child extends Parent {}
class SubChild extends Child {}
public class Test {
public static void main(String[] args) {
System.out.println("--- extends -> c ---");
testS(Child.class);
testS(SubChild.class);
//Error:Cannot be applied
//testS(Parent.class);
System.out.println("--- super c ,
public static void testS(Class extends Child> c){
System.out.println(c.getName());
}
// super c){
System.out.println(c.getName());
}
}
//2.Scala
: <: class="" plist="" person="" student="" parent="" child="" extends="" subchild="" object="" scala05_testgeneric="" def="" main="" array="" unit="{" val="" println="" tests="" type="" parameter="" bounds="" childs="" now="" is="">: Child] -> / ---")
testX(child)
testX(parent)
//!!!
testX(subChild)
println("--- [A] ---")
test0(child)
test0(parent)
test1(subChild)
println("--- test0 == test1 , ---")
}
// :
def testS[A <: child="" unit="{" println="" def="" testx="">: Child](a:A): Unit ={
println(a)
}
//
def test0[A](a:A): Unit ={
println(a)
}
def test1[Child](a:Child): Unit ={
println(a)
}
}
補足:Java Classオブジェクトの取得
public class Test {
public static void main(String[] args) throws ClassNotFoundException {
System.out.println("--- Test.class ---");
System.out.println(TestClass.class);
System.out.println("--- Class.forName ---");
System.out.println(Class.forName("TestClass"));
System.out.println("--- t.getClass ---");
TestClass t = new TestClass();
System.out.println(t.getClass());
/*Result:
--- Test.class ---
class TestClass
--- Class.forName ---
class TestClass
--- t.getClass ---
class TestClass
*/
}
}
public class TestClass {
public TestClass() {
System.out.println(" ");
}
static{
System.out.println(" ");
}
{
System.out.println(" ");
}
}
汎用マウント
//1.Java
// , ,
class Parent{}
class Child extends Parent{}
class SubChild extends Child{}
public class Test {
public static void main(String[] args) {
ArrayList std = new ArrayList();
// new SubChild ; OK
std.add(new Parent());
ArrayList childs = new ArrayList<>();
childs = std;
//Java Scala , ,
// ,
for (Child child : childs) {
//ClassCastException: Parent cannot be cast to Child
System.out.println(child);
}
}
}
//2.Scala
import scala.collection.mutable.ListBuffer
// : ,
class Student[T] {
var aaa:T = _
def test(ttt : T): Unit ={
}
}
class Parent {}
class Child extends Parent { var a = 10}
class SubChild extends Child {}
object Scala05_TestGeneric {
def main(args: Array[String]): Unit = {
//1. , Nothing,
var studs= ListBuffer[Parent]()
studs.append(new Parent)
//2.Scala ,
var childs: ListBuffer[Child] = ListBuffer[Child]()
//3. List ,
//childs = studs
}
}
暗黙パラメータ[汎用]定義
コンテキスト限定は、汎用および暗黙的な変換を組み合わせた生成物である.
// :
def f[A : B](a: A) = println(a) //
def f[A](a:A)(implicit arg:B[A]) = println(a) //
=> , , ?
//
object Scala06_TestGeneric {
def main(args: Array[String]): Unit = {
println(f2(1, 2))
}
//def [ : ]( a, b) = . (a,b)
// : [A:Ordering], , implicitly[Ordering[A]]
def f1[A:Ordering](a:A,b:A) =implicitly[Ordering[A]].compare(a,b)
/*def [ ]
( 1 : a, b)
( 2 : implicit : [ ]) = . (a,b)*/
def f2[A](a: A, b: A)(implicit ord: Ordering[A]) = ord.compare(a, b)
}