精华内容
参与话题
问答
  • Scala

    2019-11-21 21:51:59
    Scala 安装(win) scala 基础 Scala 隐式转换 Scala 字符串 Scala Array scala List scala set scala map Scala match Scala Case Scala Abs scala trait Scala paralle Scala class Scala Object scala 集合 Scala ...
    展开全文
  • scala

    千次阅读 2020-08-24 20:25:29
    scala> val a = List(1,2,3,4)a: List[Int] = List(1, 2, 3, 4) ​scala> println(a.toString)List(1, 2, 3, 4) 生成字符串 mkString方法,可以将元素以分隔符拼接起来。默认没有分隔符 参考代码 ...

    转换字符串

    toString方法可以返回List中的所有元素

    参考代码

    scala> val a = List(1,2,3,4)
    a: List[Int] = List(1, 2, 3, 4)

    scala> println(a.toString)
    List(1, 2, 3, 4)

    生成字符串

    mkString方法,可以将元素以分隔符拼接起来。默认没有分隔符

    参考代码

    scala> val a = List(1,2,3,4)
    a: List[Int] = List(1, 2, 3, 4)

    scala> a.mkString
    res7: String = 1234

    scala> a.mkString(":")
    res8: String = 1:2:3:4

    并集

    union表示对两个列表取并集,不去重

    参考代码

    scala> val a1 = List(1,2,3,4)
    a1: List[Int] = List(1, 2, 3, 4)

    scala> val a2 = List(3,4,5,6)
    a2: List[Int] = List(3, 4, 5, 6)

    // 并集操作
    scala> a1.union(a2)
    res17: List[Int] = List(1, 2, 3, 4, 3, 4, 5, 6)

    // 可以调用distinct去重
    scala> a1.union(a2).distinct
    res18: List[Int] = List(1, 2, 3, 4, 5, 6)

    交集

    intersect表示对两个列表取交集

    scala> val a1 = List(1,2,3,4)
    a1: List[Int] = List(1, 2, 3, 4)

    scala> val a2 = List(3,4,5,6)
    a2: List[Int] = List(3, 4, 5, 6)

    scala> a1.intersect(a2)
    res19: List[Int] = List(3, 4)

    差集

    diff表示对两个列表取差集,例如: a1.diff(a2),表示获取a1在a2中不存在的元素

    scala> val a1 = List(1,2,3,4)
    a1: List[Int] = List(1, 2, 3, 4)

    scala> val a2 = List(3,4,5,6)
    a2: List[Int] = List(3, 4, 5, 6)

    scala> a1.diff(a2)
    res24: List[Int] = List(1, 2)

    Set

    Set()是代表没有重复元素的集合。Set具备以下性质:

    1. 元素不重复
    2. 不保证插入顺序

    scala中的集也分为两种,一种是不可变集,另一种是可变集。

    不可变集

    语法

    创建一个空的不可变集,语法格式:

    val/var 变量名 = Set[类型]()

    给定元素来创建一个不可变集,语法格式:

    val/var 变量名 = Set(元素1, 元素2, 元素3...)

    示例一

    定义一个空的不可变集

    参考代码

    scala> val a = Set[Int]()
    a: scala.collection.immutable.Set[Int] = Set()

    示例二

    定义一个不可变集,保存以下元素:1,1,1,1,1,3,2,4,8

    参考代码

    scala> val a = Set(1,1,1,1,1,3,2,4,8)
    a: scala.collection.immutable.Set[Int] = Set(1, 2, 3, 8, 4)

    基本操作

    1. 获取集的大小(size
    2. 遍历集(和遍历数组一致
    3. 添加一个元素,生成一个Set+
    4. 拼接两个集,生成一个Set++
    5. 拼接集和列表,生成一个Set++

    示例


    参考代码

    // 创建集
    scala> val a = Set(1,1,2,3,4,5)
    a: scala.collection.immutable.Set[Int] = Set(5, 1, 2, 3, 4)

    // 获取集的大小
    scala> a.size
    res0: Int = 5

    // 遍历集
    scala> for(i <- a) println(i)

    // 删除一个元素
    scala> a - 1
    res5: scala.collection.immutable.Set[Int] = Set(5, 2, 3, 4)

    // 拼接两个集
    scala> a ++ Set(6,7,8)
    res2: scala.collection.immutable.Set[Int] = Set(5, 1, 6, 2, 7, 3, 8, 4)

    // 拼接集和列表
    scala> a ++ List(6,7,8,9)
    res6: scala.collection.immutable.Set[Int] = Set(5, 1, 6, 9, 2, 7, 3, 8, 4)

    可变集

    定义

    可变集合不可变集的创建方式一致,只不过需要提前导入一个可变集类。

    手动导入:import scala.collection.mutable.Set

    参考代码

    scala> val a = Set(1,2,3,4)
    a: scala.collection.mutable.Set[Int] = Set(1, 2, 3, 4)                          

    // 添加元素
    scala> a += 5
    res25: a.type = Set(1, 5, 2, 3, 4)

    // 删除元素s
    scala> a -= 1
    res26: a.type = Set(5, 2, 3, 4)

    映射

    Map可以称之为映射。它是由键值对组成的集合。在scala中,Map也分为不可变Map和可变Map。

    不可变Map

    语法

    val/var map = Map(->, ->, ->...) // 推荐,可读性更好
    val/var map = Map((, ), (, ), (, ), (, )...)

    参考代码

    scala> val map = Map("zhangsan"->30, "lisi"->40)
    map: scala.collection.immutable.Map[String,Int] = Map(zhangsan -> 30, lisi -> 40)

    scala> val map = Map(("zhangsan", 30), ("lisi", 30))
    map: scala.collection.immutable.Map[String,Int] = Map(zhangsan -> 30, lisi -> 30)

    // 根据key获取value
    scala> map("zhangsan")
    res10: Int = 30

    修改

    scala> map("zhangsan")=33

    <console>:11: error: value update is not a member of scala.collection.immutable.Map[String,Int]

                  map("zhangsan")=33

    可变Map

    定义

    定义语法与不可变Map一致。但定义可变Map需要手动导入import scala.collection.mutable.Map

    scala> val map = Map("zhangsan"->30, "lisi"->40)
    map: scala.collection.mutable.Map[String,Int] = Map(lisi -> 40, zhangsan -> 30)

    // 修改value
    scala> map("zhangsan") = 20

    Map基本操作

    基本操作

    1. 获取值(map(key))
    2. 获取所有keymap.keys
    3. 获取所有valuemap.values
    4. 遍历map集合
    5. getOrElse
    6. 增加key,value
    7. 删除key

    示例

    参考代码

    scala> val map = Map("zhangsan"->30, "lisi"->40)
    map: scala.collection.mutable.Map[String,Int] = Map(lisi -> 40, zhangsan -> 30)

    // 获取zhagnsan的年龄
    scala> map("zhangsan")
    res10: Int = 30

    // 获取所有的学生姓名
    scala> map.keys
    res13: Iterable[String] = Set(lisi, zhangsan)

    // 获取所有的学生年龄
    scala> map.values
    res14: Iterable[Int] = HashMap(40, 30)

    // 打印所有的学生姓名和年龄
    scala> for((x,y) <- map) println(s"$x $y")
    lisi 40
    zhangsan 30

    // 获取wangwu的年龄,如果wangwu不存在,则返回-1
    scala> map.getOrElse("wangwu", -1)
    res17: Int = -1

    // 新增一个学生:wangwu, 35
    scala> map += "wangwu"->35
    res22: scala.collection.mutable.Map[String,Int] = Map(lisi -> 40, zhangsan -> 30, wangwu -> 35)

    // lisi从可变映射中移除
    scala> map -= "lisi"
    res23: scala.collection.mutable.Map[String,Int] = Map(zhangsan -> 30)

    iterator迭代器

    scala针对每一类集合都提供了一个迭代器(iterator)用来迭代访问集合

    使用迭代器遍历集合

    1. 使用iterator方法可以从集合获取一个迭代器
    2. 迭代器的两个基本操作
      1. hasNext——查询容器中是否有下一个元素
      2. next——返回迭代器的下一个元素,如果没有,抛出NoSuchElementException
    3. 每一个迭代器都是有状态的
    4. 迭代完后保留在最后一个元素的位置
    5. 再次使用则抛出NoSuchElementException
    6. 可以使用while或者for来逐个返回元素

    示例

    1. 定义一个列表,包含以下元素:1,2,3,4,5
    2. 使用while循环和迭代器,遍历打印该列表

    参考代码

    scala> var a=List(1,2,3,4,5)

    a: List[Int] = List(1, 2, 3, 4, 5)

     

    scala> val ite = a.iterator
    ite: Iterator[Int] = non-empty iterator

    scala> while(ite.hasNext){

    println(ite.next)

    }

    示例

    1. 定义一个列表,包含以下元素:1,2,3,4,5
    2. 使用for 表达式和迭代器,遍历打印该列表

    参考代码

    scala> val a = List(1,2,3,4,5)
    a: List[Int] = List(1, 2, 3, 4, 5)

    scala> for(i <- a) println(i)

     

    展开全文
  • Scala Predef对象详解

    万次阅读 2018-11-16 13:39:14
    Scala Predef对象 Scala程序设计 第2版 - 原版.pdf 下载:https://download.csdn.net/download/u014646662/10805074 目录: 1.Predef源码 2.类型装换 3.类型定义 4.条件检查方法 5.输入输出方法 6.其他 对...

    Scala Predef对象

    Scala程序设计 第2版 - 原版.pdf 下载:https://download.csdn.net/download/u014646662/10805074

    目录:

    1.Predef源码

    2.类型装换

    3.类型定义

    4.条件检查方法

    5.输入输出方法

    6.其他

    对人工智能感兴趣的同学,可以点击以下链接:

    现在人工智能非常火爆,很多朋友都想学,但是一般的教程都是为博硕生准备的,太难看懂了。最近发现了一个非常适合小白入门的教程,不仅通俗易懂而且还很风趣幽默。所以忍不住分享一下给大家。点这里可以跳转到教程。

    https://www.cbedai.net/u014646662

    1 Predef源码

    为了方便起见,只要你编译代码,Scala 编译器就会自动导入顶层Scala 包(名为scala)以及在java.lang 包(就像javac 的)中的定义。因此,许多常见的Java 和Scala 类型都可以不经过明显地导入或提供完整的名称就可以使用。另外,编译器还导入了Predef 对象中的一些定。接下来,我们来详细了解Predef 提供的特性。需要注意的是,Scala 2.11 版本的Predef 引入了很多变化,其中大部分是不可见的。

    看一看源码:

    package scala
    object Predef extends scala.LowPriorityImplicits with scala.DeprecatedPredef {
      def classOf[T] : Predef.Class[T] = { /* compiled code */ }
      type Class[T] = java.lang.Class[T]
      type String = java.lang.String
      type Function[-A, +B] = scala.Function1[A, B]
      type Map[A, +B] = scala.collection.immutable.Map[A, B]
      type Set[A] = scala.collection.immutable.Set[A]
      val Map : scala.collection.immutable.Map.type = { /* compiled code */ }
      val Set : scala.collection.immutable.Set.type = { /* compiled code */ }
      @scala.deprecated("use `scala.reflect.ClassTag` instead", "2.10.0")
      @scala.annotation.implicitNotFound("No ClassManifest available for ${T}.")
      type ClassManifest[T] = scala.reflect.ClassManifest[T]
      type OptManifest[T] = scala.reflect.OptManifest[T]
      @scala.annotation.implicitNotFound("No Manifest available for ${T}.")
      type Manifest[T] = scala.reflect.Manifest[T]
      @scala.deprecated("use `scala.reflect.ClassTag` instead", "2.10.0")
      val ClassManifest : scala.reflect.ClassManifestFactory.type = { /* compiled code */ }
      val Manifest : scala.reflect.ManifestFactory.type = { /* compiled code */ }
      val NoManifest : scala.reflect.NoManifest.type = { /* compiled code */ }
      def manifest[T](implicit m : Predef.Manifest[T]) : Predef.Manifest[T] = { /* compiled code */ }
      @scala.deprecated("use scala.reflect.classTag[T] instead", "2.10.0")
      def classManifest[T](implicit m : Predef.ClassManifest[T]) : Predef.ClassManifest[T] = { /* compiled code */ }
      def optManifest[T](implicit m : Predef.OptManifest[T]) : Predef.OptManifest[T] = { /* compiled code */ }
      @scala.inline
      def identity[A](x : A) : A = { /* compiled code */ }
      @scala.inline
      def implicitly[T](implicit e : T) : T = { /* compiled code */ }
      @scala.inline
      def locally[T](x : T) : T = { /* compiled code */ }
      @scala.annotation.elidable(2000)
      def assert(assertion : scala.Boolean) : scala.Unit = { /* compiled code */ }
      @scala.inline
      @scala.annotation.elidable(2000)
      final def assert(assertion : scala.Boolean, message : => scala.Any) : scala.Unit = { /* compiled code */ }
      @scala.annotation.elidable(2000)
      def assume(assumption : scala.Boolean) : scala.Unit = { /* compiled code */ }
      @scala.inline
      @scala.annotation.elidable(2000)
      final def assume(assumption : scala.Boolean, message : => scala.Any) : scala.Unit = { /* compiled code */ }
      def require(requirement : scala.Boolean) : scala.Unit = { /* compiled code */ }
      @scala.inline
      final def require(requirement : scala.Boolean, message : => scala.Any) : scala.Unit = { /* compiled code */ }
      def ??? : scala.Nothing = { /* compiled code */ }
      @scala.deprecated("use built-in tuple syntax or Tuple2 instead", "2.11.0")
      type Pair[+A, +B] = scala.Tuple2[A, B]
      @scala.deprecated("use built-in tuple syntax or Tuple2 instead", "2.11.0")
      object Pair extends scala.AnyRef {
        def apply[A, B](x : A, y : B) : scala.Tuple2[A, B] = { /* compiled code */ }
        def unapply[A, B](x : scala.Tuple2[A, B]) : scala.Option[scala.Tuple2[A, B]] = { /* compiled code */ }
      }
      @scala.deprecated("use built-in tuple syntax or Tuple3 instead", "2.11.0")
      type Triple[+A, +B, +C] = scala.Tuple3[A, B, C]
      @scala.deprecated("use built-in tuple syntax or Tuple3 instead", "2.11.0")
      object Triple extends scala.AnyRef {
        def apply[A, B, C](x : A, y : B, z : C) : scala.Tuple3[A, B, C] = { /* compiled code */ }
        def unapply[A, B, C](x : scala.Tuple3[A, B, C]) : scala.Option[scala.Tuple3[A, B, C]] = { /* compiled code */ }
      }
      implicit final class ArrowAssoc[A](self : A) extends scala.AnyVal {
        @scala.inline
        def ->[B](y : B) : scala.Tuple2[A, B] = { /* compiled code */ }
        def →[B](y : B) : scala.Tuple2[A, B] = { /* compiled code */ }
      }
      implicit final class Ensuring[A](self : A) extends scala.AnyVal {
        def ensuring(cond : scala.Boolean) : A = { /* compiled code */ }
        def ensuring(cond : scala.Boolean, msg : => scala.Any) : A = { /* compiled code */ }
        def ensuring(cond : scala.Function1[A, scala.Boolean]) : A = { /* compiled code */ }
        def ensuring(cond : scala.Function1[A, scala.Boolean], msg : => scala.Any) : A = { /* compiled code */ }
      }
      implicit final class StringFormat[A](self : A) extends scala.AnyVal {
        @scala.inline
        def formatted(fmtstr : Predef.String) : Predef.String = { /* compiled code */ }
      }
      implicit final class any2stringadd[A](self : A) extends scala.AnyVal {
        def +(other : Predef.String) : Predef.String = { /* compiled code */ }
      }
      implicit final class RichException(self : scala.Throwable) extends scala.AnyVal {
        @scala.deprecated("use Throwable#getStackTrace", "2.11.0")
        def getStackTraceString : _root_.scala.Predef.String = { /* compiled code */ }
      }
      implicit final class SeqCharSequence(@scala.deprecated("will be made private", "2.12.0") val __sequenceOfChars : scala.collection.IndexedSeq[scala.Char]) extends java.lang.Object with java.lang.CharSequence {
        def length() : scala.Int = { /* compiled code */ }
        def charAt(index : scala.Int) : scala.Char = { /* compiled code */ }
        def subSequence(start : scala.Int, end : scala.Int) : java.lang.CharSequence = { /* compiled code */ }
        override def toString() : _root_.scala.Predef.String = { /* compiled code */ }
      }
      implicit final class ArrayCharSequence(@scala.deprecated("will be made private", "2.12.0") val __arrayOfChars : scala.Array[scala.Char]) extends java.lang.Object with java.lang.CharSequence {
        def length() : scala.Int = { /* compiled code */ }
        def charAt(index : scala.Int) : scala.Char = { /* compiled code */ }
        def subSequence(start : scala.Int, end : scala.Int) : java.lang.CharSequence = { /* compiled code */ }
        override def toString() : _root_.scala.Predef.String = { /* compiled code */ }
      }
      implicit val StringCanBuildFrom : scala.collection.generic.CanBuildFrom[Predef.String, scala.Char, Predef.String] = { /* compiled code */ }
      @scala.inline
      implicit def augmentString(x : Predef.String) : scala.collection.immutable.StringOps = { /* compiled code */ }
      @scala.inline
      implicit def unaugmentString(x : scala.collection.immutable.StringOps) : Predef.String = { /* compiled code */ }
      def print(x : scala.Any) : scala.Unit = { /* compiled code */ }
      def println() : scala.Unit = { /* compiled code */ }
      def println(x : scala.Any) : scala.Unit = { /* compiled code */ }
      def printf(text : Predef.String, xs : scala.Any*) : scala.Unit = { /* compiled code */ }
      implicit def tuple2ToZippedOps[T1, T2](x : scala.Tuple2[T1, T2]) : scala.runtime.Tuple2Zipped.Ops[T1, T2] = { /* compiled code */ }
      implicit def tuple3ToZippedOps[T1, T2, T3](x : scala.Tuple3[T1, T2, T3]) : scala.runtime.Tuple3Zipped.Ops[T1, T2, T3] = { /* compiled code */ }
      implicit def genericArrayOps[T](xs : scala.Array[T]) : scala.collection.mutable.ArrayOps[T] = { /* compiled code */ }
      implicit def booleanArrayOps(xs : scala.Array[scala.Boolean]) : scala.collection.mutable.ArrayOps.ofBoolean = { /* compiled code */ }
      implicit def byteArrayOps(xs : scala.Array[scala.Byte]) : scala.collection.mutable.ArrayOps.ofByte = { /* compiled code */ }
      implicit def charArrayOps(xs : scala.Array[scala.Char]) : scala.collection.mutable.ArrayOps.ofChar = { /* compiled code */ }
      implicit def doubleArrayOps(xs : scala.Array[scala.Double]) : scala.collection.mutable.ArrayOps.ofDouble = { /* compiled code */ }
      implicit def floatArrayOps(xs : scala.Array[scala.Float]) : scala.collection.mutable.ArrayOps.ofFloat = { /* compiled code */ }
      implicit def intArrayOps(xs : scala.Array[scala.Int]) : scala.collection.mutable.ArrayOps.ofInt = { /* compiled code */ }
      implicit def longArrayOps(xs : scala.Array[scala.Long]) : scala.collection.mutable.ArrayOps.ofLong = { /* compiled code */ }
      implicit def refArrayOps[T <: scala.AnyRef](xs : scala.Array[T]) : scala.collection.mutable.ArrayOps.ofRef[T] = { /* compiled code */ }
      implicit def shortArrayOps(xs : scala.Array[scala.Short]) : scala.collection.mutable.ArrayOps.ofShort = { /* compiled code */ }
      implicit def unitArrayOps(xs : scala.Array[scala.Unit]) : scala.collection.mutable.ArrayOps.ofUnit = { /* compiled code */ }
      implicit def byte2Byte(x : scala.Byte) : java.lang.Byte = { /* compiled code */ }
      implicit def short2Short(x : scala.Short) : java.lang.Short = { /* compiled code */ }
      implicit def char2Character(x : scala.Char) : java.lang.Character = { /* compiled code */ }
      implicit def int2Integer(x : scala.Int) : java.lang.Integer = { /* compiled code */ }
      implicit def long2Long(x : scala.Long) : java.lang.Long = { /* compiled code */ }
      implicit def float2Float(x : scala.Float) : java.lang.Float = { /* compiled code */ }
      implicit def double2Double(x : scala.Double) : java.lang.Double = { /* compiled code */ }
      implicit def boolean2Boolean(x : scala.Boolean) : java.lang.Boolean = { /* compiled code */ }
      implicit def Byte2byte(x : java.lang.Byte) : scala.Byte = { /* compiled code */ }
      implicit def Short2short(x : java.lang.Short) : scala.Short = { /* compiled code */ }
      implicit def Character2char(x : java.lang.Character) : scala.Char = { /* compiled code */ }
      implicit def Integer2int(x : java.lang.Integer) : scala.Int = { /* compiled code */ }
      implicit def Long2long(x : java.lang.Long) : scala.Long = { /* compiled code */ }
      implicit def Float2float(x : java.lang.Float) : scala.Float = { /* compiled code */ }
      implicit def Double2double(x : java.lang.Double) : scala.Double = { /* compiled code */ }
      implicit def Boolean2boolean(x : java.lang.Boolean) : scala.Boolean = { /* compiled code */ }
      @scala.annotation.implicitNotFound("Cannot prove that ${From} <:< ${To}.")
      sealed abstract class <:<[-From, +To]() extends scala.AnyRef with scala.Function1[From, To] with scala.Serializable {
        
      }
      implicit def $conforms[A] : Predef.<:<[A, A] = { /* compiled code */ }
      @scala.deprecated("use `implicitly[T <:< U]` or `identity` instead.", "2.11.0")
      def conforms[A] : Predef.<:<[A, A] = { /* compiled code */ }
      @scala.annotation.implicitNotFound("Cannot prove that ${From} =:= ${To}.")
      sealed abstract class =:=[From, To]() extends scala.AnyRef with scala.Function1[From, To] with scala.Serializable {
        
      }
      object =:= extends scala.AnyRef with scala.Serializable {
        implicit def tpEquals[A] : Predef.=:=[A, A] = { /* compiled code */ }
      }
      class DummyImplicit() extends scala.AnyRef {
      }
      object DummyImplicit extends scala.AnyRef {
        implicit def dummyImplicit : Predef.DummyImplicit = { /* compiled code */ }
      }
    }
    

    2 类型转换

    implicit def byte2Byte(x : scala.Byte) : java.lang.Byte = { /* compiled code */ }
      implicit def short2Short(x : scala.Short) : java.lang.Short = { /* compiled code */ }
      implicit def char2Character(x : scala.Char) : java.lang.Character = { /* compiled code */ }
      implicit def int2Integer(x : scala.Int) : java.lang.Integer = { /* compiled code */ }
      implicit def long2Long(x : scala.Long) : java.lang.Long = { /* compiled code */ }
      implicit def float2Float(x : scala.Float) : java.lang.Float = { /* compiled code */ }
      implicit def double2Double(x : scala.Double) : java.lang.Double = { /* compiled code */ }
      implicit def boolean2Boolean(x : scala.Boolean) : java.lang.Boolean = { /* compiled code */ }
      implicit def Byte2byte(x : java.lang.Byte) : scala.Byte = { /* compiled code */ }
      implicit def Short2short(x : java.lang.Short) : scala.Short = { /* compiled code */ }
      implicit def Character2char(x : java.lang.Character) : scala.Char = { /* compiled code */ }
      implicit def Integer2int(x : java.lang.Integer) : scala.Int = { /* compiled code */ }
      implicit def Long2long(x : java.lang.Long) : scala.Long = { /* compiled code */ }
      implicit def Float2float(x : java.lang.Float) : scala.Float = { /* compiled code */ }
      implicit def Double2double(x : java.lang.Double) : scala.Double = { /* compiled code */ }
      implicit def Boolean2boolean(x : java.lang.Boolean) : scala.Boolean = { /* compiled code */ }

    3 类型定义

    Predef 定义了若干的类型及类型别名。为了鼓励使用不可变集合,Predef 为最常用的不可变集合定义了别名:

    type Class[T] = java.lang.Class[T]
    type String = java.lang.String
    type Map[A, +B] = scala.collection.immutable.Map[A, B]
    type Set[A] = scala.collection.immutable.Set[A]
    type Function[-A, +B] = scala.Function1[A, B]
    val Map : scala.collection.immutable.Map.type = { /* compiled code */ }
    val Set : scala.collection.immutable.Set.type = { /* compiled code */ }

    支持类型推断的其他一些Predef 类型。

    我们经常使用a -> b(或等价的a → b)这种写法:

    object Test {
      def main(args: Array[String]): Unit = {
    
        val a = (1, "one")
        val b = 1 -> "one"
        val c = 1 → "one"
        println(a) //输出:(1,one)
        println(b) //输出:(1,one)
        println(c) //输出:(1,one)
        val map = Map("one" -> 1, "two" -> 2)
        println(map) //输出:Map(one -> 1, two -> 2)
      }
    }

    事实上,Scala 根本不知道a -> b 意味着什么,因此上述方法并非没有意义。这种“字面量”格式实际上运用了方法-> 和一个特殊的Scala 特性——隐式转换。通过运用隐式转换,我们可以在任意两种类型值之间插入函数->。与此同时,由于a -> b 并不是元组的字面量语法,因此Scala 必须通过某些方式将该表达式转化为元组(a, b)。

    很明显,->之所以能用,就是因为我们已经把->方法定义好了,也就是 ArrowAssoc的->方法,源码如下

      implicit final class ArrowAssoc[A](self : A) extends scala.AnyVal {
        @scala.inline
        def ->[B](y : B) : scala.Tuple2[A, B] = { /* compiled code */ }
        def →[B](y : B) : scala.Tuple2[A, B] = { /* compiled code */ }
      }

    在此只因关键字implicit起的作用,具体执行过程:

    (1) 编译器发现我们试图对String 对象执行-> 方法(例如“ one” -> 1)。
    (2) 由于String 未定义-> 方法,编译器将检查当前作用域中是否存在定义了该方法的隐式转换。
    (3) 编译器发现了ArrowAssoc 类。
    (4) 编译器将创建ArrowAssoc 对象,并向其传入one 字符串。
    (5) 之后,编译器将解析表达式中的-> 1 部分代码,并确认了整个表达式的类型与Map.apply 方法的预期类型相吻合,即两者均为pair 实例。

    如果希望执行隐式转换,那么在声明时必须使用implicit 关键字,能够执行隐式转换的无外乎两类:构造方法中只接受单一参数的类型或者是只接受单一参数的方法。

    为了限定参数类型,Scala有了隐式证据<:<,在哪里用到了呢?

    package cn.com.tengen.test.obj
    
    object Test {
      def main(args: Array[String]): Unit = {
    
        val map = Map("one" -> 1, "two" -> 2)
        println(map.toMap) //输出:Map(one -> 1, two -> 2)
    
        val list1 = List((1,"aa"),(2,"bb"),(3,"cc"),(4,"dd"))
        println(list1.toMap) //Map(1 -> aa, 2 -> bb, 3 -> cc, 4 -> dd)
    
        val list2 = List(1,2,3,4)
        println(list2.toMap) //抛出异常
      }
    }
    
      @scala.annotation.implicitNotFound("Cannot prove that ${From} <:< ${To}.")
      sealed abstract class <:<[-From, +To]() extends scala.AnyRef with scala.Function1[From, To] with scala.Serializable {
        
      }
    package scala.collection
    
    trait TraversableOnce[+A] extends scala.Any with scala.collection.GenTraversableOnce[A] {
        ...
      def toMap[T, U](implicit ev: _root_.scala.Predef.<:<[A, scala.Tuple2[T, U]]): scala.collection.immutable.Map[T, U] = {
        /* compiled code */
      }
        ...
    }

    4 条件检查方法

    有时你希望断言某条件为真,希望它“快速失败”(尤其在测试时)。Predef 定义了许多有助于达到这个目的的方法。

    • def assert(assertion: Boolean)
    测试条件是否为真,如果不为真,抛出java.lang.AssertionError 异常。
    • def assert(assertion: Boolean, message: => Any)
    类似前面的assert,但增加了一个可选参数,该参数将被转为错误信息字符串。
    • def assume(assertion: Boolean)
    与assert 相同,但其表示当一段代码块(如方法)正确时,条件才为真。
    • def assume(assertion: Boolean, message: => Any)
    类似前面的assume,但增加了一个可选参数,该参数将被转为错误信息字符串。
    • def require(requirement: Boolean)
    与assume 相同,但根据Scaladoc,其含义是调用方是否满足某些条件,也可以表示某个实现不能得出特定的结果。
    • def require(requirement: Boolean, message: => Any)
    类似前面的require,但增加了一个可选参数,该参数将被转为错误信息字符串。

    5 输入输出方法

    Scala把数据打印到控制台,这是我们经常做的操作,其实他也是Predef定义的。Predef 为我们提供了四种将字符串打印到stdout 的形式。

      def print(x : scala.Any) : scala.Unit = { /* compiled code */ }
      def println() : scala.Unit = { /* compiled code */ }
      def println(x : scala.Any) : scala.Unit = { /* compiled code */ }
      def printf(text : Predef.String, xs : scala.Any*) : scala.Unit = { /* compiled code */ }

    • def print(x: Any): Unit
    将x 转为字符串,然后写到标准输出,结尾不会自动添加换行。
    • def printf(format: String, xs: Any*): Unit
    用format 和其他参数xs 对printf 风格的字符串进行格式化,然后将结果写到标准输出,结尾不会自动添加换行。
    • def println(x: Any): Unit
    类似print,但结尾会自动添加换行。
    • def println(): Unit
    向标准输出打印空行。

    在老的版本中(2.12之前)Predef提供了相当多的输入方法:

    @scala.deprecated("use the method in `scala.io.StdIn`", "2.11.0")
      def readLine() : DeprecatedPredef.super[Predef/*scala.Predef*/].String = { /* compiled code */ }
      @scala.deprecated("use the method in `scala.io.StdIn`", "2.11.0")
      def readLine(text : DeprecatedPredef.super[Predef/*scala.Predef*/].String, args : scala.Any*) : _root_.scala.Predef.String = { /* compiled code */ }
      @scala.deprecated("use the method in `scala.io.StdIn`", "2.11.0")
      def readBoolean() : scala.Boolean = { /* compiled code */ }
      @scala.deprecated("use the method in `scala.io.StdIn`", "2.11.0")
      def readByte() : scala.Byte = { /* compiled code */ }
      @scala.deprecated("use the method in `scala.io.StdIn`", "2.11.0")
      def readShort() : scala.Short = { /* compiled code */ }
      @scala.deprecated("use the method in `scala.io.StdIn`", "2.11.0")
      def readChar() : scala.Char = { /* compiled code */ }
      @scala.deprecated("use the method in `scala.io.StdIn`", "2.11.0")
      def readInt() : scala.Int = { /* compiled code */ }
      @scala.deprecated("use the method in `scala.io.StdIn`", "2.11.0")
      def readLong() : scala.Long = { /* compiled code */ }
      @scala.deprecated("use the method in `scala.io.StdIn`", "2.11.0")
      def readFloat() : scala.Float = { /* compiled code */ }
      @scala.deprecated("use the method in `scala.io.StdIn`", "2.11.0")
      def readDouble() : scala.Double = { /* compiled code */ }
      @scala.deprecated("use the method in `scala.io.StdIn`", "2.11.0")
      def readf(format : DeprecatedPredef.super[Predef/*scala.Predef*/].String) : scala.List[scala.Any] = { /* compiled code */ }
      @scala.deprecated("use the method in `scala.io.StdIn`", "2.11.0")
      def readf1(format : DeprecatedPredef.super[Predef/*scala.Predef*/].String) : scala.Any = { /* compiled code */ }
      @scala.deprecated("use the method in `scala.io.StdIn`", "2.11.0")
      def readf2(format : DeprecatedPredef.super[Predef/*scala.Predef*/].String) : scala.Tuple2[scala.Any, scala.Any] = { /* compiled code */ }
      @scala.deprecated("use the method in `scala.io.StdIn`", "2.11.0")
      def readf3(format : DeprecatedPredef.super[Predef/*scala.Predef*/].String) : scala.Tuple3[scala.Any, scala.Any, scala.Any] = { /* compiled code */ }

    • def readBoolean(): Boolean
    从标准输入的一个整行中读取一个Boolean 值。
    • def readByte(): Byte
    从标准输入的一个整行中读取一个Byte 值。
    • def readChar(): Char
    从标准输入的一个整行中读取一个Char 值。
    • def readDouble(): Double
    从标准输入的一个整行中读取一个Double 值。
    • def readFloat(): Float
    从标准输入的一个整行中读取一个Float 值。
    • def readInt(): Int
    从标准输入的一个整行中读取一个Int 值。
    • def readLine(text: String, args: Any*): String
    向标准输出中打印格式化的提示文本,并从标准输入中读取一整行字符串。
    • def readLine(): String
    从标准输入中读取一整行字符串。
    • def readLong(): Long
    从标准输入的一个整行中读取一个Long 值。
    • def readShort(): Short
    从标准输入的一个整行中读取一个Short 值。
    • def readf(format: String): List[Any]
    根据format 中的区分符号,从标准输入中读取格式化输入。
    • def readf1(format: String): Any
    根据format 中的区分符号,从标准输入中读取格式化输入。并根据format 的指定,返回提取的第一个值。

    • def readf2(format: String): (Any, Any)
    根据format 中的区分符号,从标准输入中读取格式化输入。并根据format 的指定,返回提取的前两个值。
    • def readf3(format: String): (Any, Any, Any)
    根据format 中的区分符号,从标准输入中读取格式化输入。并根据format 的指定,返回提取的前三个值。

    在输入时也可以选择Java的方式:

      val read:Scanner = new Scanner(System.in)
      val line = read.nextLine()
      val b = read.nextByte()
      val s = read.nextShort()
      val i = read.nextInt()
      val f = read.nextFloat()
      val d = read.nextDouble()
      val l = read.nextLong()
      val bool = read.nextBoolean()

    6 杂项方法

    1 ???

    在一个尚未实现的方法的方法体中调用。它为方法提供了具体的定义,允许编译器将方法所属的类型视为具体(与抽象对应)的类。然而,如果调用该方法,就会抛出scala.NotImplementedError 异常。源码如下:

    def ??? : scala.Nothing = { /* compiled code */ }

    2 identity

    直接返回参数x。在将方法传给组合器(combinator)时,如果不需要进行修改,就可以用它。例如:在一个工作流程中,我们通过给map 传入一个函数来对集合元素进行转化。有时我们不需要做任何转化,你可以传入identity。源码如下:

    @scala.inline
      def identity[A](x : A) : A = { /* compiled code */ }

    3 implicitly

    当隐式参数列表使用简写[T:M] 时,编译器会添加形式为(implicit arg: M[T]) 的隐式参数列表(实际名称不是arg,而是编译器合成的唯一名称)。调用implicitly 可以返回参数arg。源码如下:

     @scala.inline
      def implicitly[T](implicit e : T) : T = { /* compiled code */ }

    看一个例子:

    package cn.com.tengen.test.obj
    
    class Test{
    
    }
    case class MyList[A](list: List[A]) {
      def sortBy1[B](f: A => B)(implicit ord: Ordering[B]): List[A] =
        list.sortBy(f)(ord)
      def sortBy2[B : Ordering](f: A => B): List[A] =
        list.sortBy(f)(implicitly[Ordering[B]])
    }
    
    
    object Test {
      def main(args: Array[String]): Unit = {
        val list = MyList(List(1,3,5,2,4))
        val l1 = list sortBy1 (i => -i)
        val l2 = list sortBy2 (i => -i)
        println(l1)
        println(l2)
      }
    }
    有些集合提供了一些排序方法,List.sortBy 便是其中之一。List.sortBy 方法的第一个参数类型为函数,该输入函数能够将函数的输入参数转化为另一个满足math.Ordering 条件的类型。而math.Ordering 是与Java 中的Comparable抽象等同的类型。List.sortBy 方法的另一个参数则为隐式参数,该参数知道如何对类型B 的实例进行排序。
    
    MyList 类提供了两种方式编写像sortBy 类型的方法。第一种实现:sortBy1 方法应用了我们已知的语法。该方法接受一个额外的类型为Ordering[B] 的隐式值作为其输入。调用sortBy1 方法时,在当前作用域中一定存在某一Ordering[B] 的对象实例,该实例清楚地知道如何对我们所需要的B 类型对象进行排序。我们认为B 的界限被“上下文”所限定,在这个例子中,上下文限定了B 对实例进行排序的能力。
    
    由于这种Scala 方言应用非常普遍,因此Scala 提供了一个简化版的语法,这正是第二类实现 sortBy2 所使用的语法。类型参数B : Ordering被称为 上下文定界( context bound), 它暗指第二个参数列表(也就是那个隐式参数列表)将接受Ordering[B] 实例。
    
    不过,我们仍需要在方法中访问Ordering 对象实例。由于在源代码中我们不再明确地声明Ordering 对象实例,因此这个实例没有自己的名称。针对这种现象我们该怎么办呢?Predef.implicitly 方法帮我们解决了这个问题。implicitly 方法会对传给函数的所有标记为隐式参数的实例进行解析。请注意implicitly 方法所需要的类型签名,在本例中Ordering[B] 是其类型签名。
    
    4.Pair 与 Triple
    
    Pair是一个二元组,Triple是一个三元组
    源码:
    
    @scala.deprecated("use built-in tuple syntax or Tuple2 instead", "2.11.0")
      type Pair[+A, +B] = scala.Tuple2[A, B]
      @scala.deprecated("use built-in tuple syntax or Tuple2 instead", "2.11.0")
      object Pair extends scala.AnyRef {
        def apply[A, B](x : A, y : B) : scala.Tuple2[A, B] = { /* compiled code */ }
        def unapply[A, B](x : scala.Tuple2[A, B]) : scala.Option[scala.Tuple2[A, B]] = { /* compiled code */ }
      }
      @scala.deprecated("use built-in tuple syntax or Tuple3 instead", "2.11.0")
      type Triple[+A, +B, +C] = scala.Tuple3[A, B, C]
      @scala.deprecated("use built-in tuple syntax or Tuple3 instead", "2.11.0")
      object Triple extends scala.AnyRef {
        def apply[A, B, C](x : A, y : B, z : C) : scala.Tuple3[A, B, C] = { /* compiled code */ }
        def unapply[A, B, C](x : scala.Tuple3[A, B, C]) : scala.Option[scala.Tuple3[A, B, C]] = { /* compiled code */ }
      }
    5. Map与Set
    
    我们先可一个例子:
    
    object Test {
      def main(args: Array[String]): Unit = {
        val map = Map(1->"aaa",2->"BBB")
        val set = Set(1,2,33,44,44,6)
        println(map)
        println(set)
      }
    }

    这里我们用的Map和Set都是Predef中的两个属性,而并没有直接导入scala.collection.immutable.Map和scala.collection.immutable.Set,看源码:

     type Map[A, +B] = scala.collection.immutable.Map[A, B]
      type Set[A] = scala.collection.immutable.Set[A]
      val Map : scala.collection.immutable.Map.type = { /* compiled code */ }
      val Set : scala.collection.immutable.Set.type = { /* compiled code */ }

     

    展开全文

空空如也

1 2 3 4 5 ... 20
收藏数 98,248
精华内容 39,299
关键字:

scala