notes for TOUR OF SCALA/efficient scala/programming in scala(scala always to be continue)

official website https://docs.scala-lang.org/tour/variances.html

all codes for testing : https://github.com/yuqingwang15/scala-coding

some snippets: http://www.cnblogs.com/yumanman/p/7612689.html 

----------

访问object、class、trait内部

将 object、class、trait作为参数

返回object、class、trait

----------

 compilation units:  IntFloatArray or Option

----------

package {type member / value member}

tyep member{class/trait} 

vlaue{object /def}

----------

class{type/value/shadowed implict/instance contructors}

trait{abstract def / concrete def}

object{value}  

----------

class extends class

object extends class

trait extends class

----------

class: abstract , sealed ,case ,

----------

  • def的parameters必须属于一种type。
  • object B extends Cwith t,因此object不能被extends,若需要使用内部成员,可1import--即为引入,对象可为具有access权限的任何(class,method,object,trait...)2implicit convert 如 implicit def xtoy(x:X.type) = Y3将该成员取出放入一个trait中
  • !!!:object o extends C with t{}

 

    1. declares an anonymous (inaccessible) class that extends both B and C, and
    2. creates a single instance of this class named A.
    3. This means A can be passed to functions expecting objects of type B or C, and method f can be called using A.f(...).
  • trait /object 不能有参数, extends /abstract 区别了trait和class

 

---------- 

1  class classname(parameters){...}

  • (parameters)

如果不写var/val,则视为private classobjectname.parameters,其他类实例访问无法编译成功。(private 见link

class Calculator(brand: String) class ScientificCalculator(brand: String) extends Calculator(brand)

 

如果赋初始值,那么new时传参可有可无。否则必须有相同个数类型的参数传入才能够construct成功。

  • private var

同名object与class通信即companion, class中import之后,可访问object值。

同名object中new class可访问class中private值。

class自身通过def funcname 来访问私有成员。

2  method&function

  1. 可匿名
  2. var a = ()=>4 a被implicit看做指向function的指针。a()返回function返回值,a返回function自身。
  3. res0: () => Int = $$Lambda$1000/1271084832@2dd0f797  func为一个object有一个Int值
  4. 参数为空也是有参数。参数不需var/val
  5. 函数即对象:函数是一些特质的集合。具体来说,具有一个参数的函数是Function1特质的一个实例。这个特征定义了apply()语法糖,让你调用一个对象时就像你在调用一个函数
  6. object addOne extends Function1[Int, Int] { def apply(m: Int): Int = m + 1 } >addOne(1) res2: Int = 2

 

    1. 这个Function特质集合下标从0开始一直到22。为什么是22?这是一个主观的魔幻数字(magic number)。我从来没有使用过多于22个参数的函数,所以这个数字似乎是合理的。
    2. apply语法糖有助于统一对象和函数式编程的二重性。你可以传递类,并把它们当做函数使用,而函数本质上是类的实例。
    3. !!:class extends class,object也可以extends class。object可以像函数被用,函数和object都可以是traits的集合。trait里可有abstract def可有concrete def,trait同样可以被new。

3  class

  1. 通过参数是否有var 表明private or public  constructor
  2. Parameters without val or var are private values, visible only within the class.  constructor
  3. classa(var str:String) ,extends时str 需要指明
  4. one superclass but many mixins   extends。可以将trait和class组合成一个新class,像多个def 组合在一个def里。
  5. 当class or trait有sealed标记时 we don’t need a “catch all” case

4  traits

  1. 在trait中def hasNext:Boolean或var hasNext:Boolean override时分别为def hasNext: Boolean = 3<3    val hasNext: Boolean = 3<3  两者完全一样
  2. Subtypes of traits 有点类似于抽象类的子类
  3. 什么时候应该使用特质而不是抽象类?

5  case class & pattern matching

  1. 样本类也可以像普通类那样拥有方法。
  2. case classes have an apply method by default which takes care of object construction.因此“样本类”不需要new
  3. When you create a case class with parameters, the parameters are public vals.因此不能再赋值,参数不能有var/val
  4. compared by structure and not by reference 因此即使指向不同的object也会看具体value是否相同
  5. by using the copy method. You can optionally change the constructor arguments.注意是可选参数的shallow copy
  6. In the case Email(email, _, _) if importantPeopleInfo.contains(email), the pattern is matched only if the email is in the list of important people.和if <boolean expression>连用,相当于case之下再进行对参数的筛选
  7. case class在abstract class之下即对abstract的不同继承
  8. 想要在pattern中call a method,在case是否某一类时最好用class identifier的第一个字母表示 case p:Phone=>p.sendMsg
  9. match: 有时用参数来match,有时只match a type 
  10. _ 通配 否则当传进一个不能被匹配的数字的时候,你将获得一个运行时错误

6  currying

  1. When a method is called with a fewer number of parameter lists, then this will yield a function taking the missing parameter lists as its arguments.

7  sealed

  1. Traits and classes can be marked sealed which means all subtypes must be declared in the same file. The assures that all subtypes are known.

8  singleton objects

  1. 其中的method available globally。因此可以  referred to, or imported
  2. case class with no type parameters will by default create a singleton object of the same name, with a Function* trait implemented.  
  3. 伴生不在一起定义时出现warning
  4. 可继承classes and traits
  5. companions即类与object同名,需要在一个source file里定义。另 Scaladoc直接可跳转,符号:C与O。我们通常将伴生对象作为工厂使用。
  6. all members that would be static, including classes, should go in a singleton object.(java中使用的是static)
  7. 值和函数不能在类或单例对象之外定义。单例对象是组织静态函数(static function)的有效工具。

9  implicit

  1. A method with implicit parameters can be applied to arguments just like a normal method.
  2. implicit values can not be top-level, they have to be members of a template.

  3. if such a method misses arguments for its implicit parameters, such arguments will be automatically provided.并且 actual arguments for implicit parameters 可分为两类
  4. 第一类:all identifiers x that can be accessed at the point of the method call without a prefix and that denote an implicit definition or an implicit parameter.即implicitly find在目前scope中有同样type的val或object替代这个参数
  5. 第二:all members of companion modules of the implicit parameter’s type that are labeled implicit.即implicit parameter’type 的所有companion成员
  6. static:

10  extractor object

  1. an object with an unapply method(unapply: takes an object and tries to give back the arguments)
  2. case CustomerID(name) =>   或  val CustomerID(name) = customer2ID相当于val name = CustomerID.unapply(customer2ID).get
  3. CustomerID("wang")是call apply,CustomerID(name)是call unapply 并且可通过.get得到name   赋值的表达式本质还是match方法
  4. unapply方法的返回:Boolean或Option[T]或Option[(T1,...,Tn)] 或Option[Seq[T]]
  5.  define patterns through unapplySeqwhich returns Option[Seq[T]] This mechanism is used for instance in pattern case List(x1, ..., xn).--需要返回的sub-value个数不确定时

11  sequence comprehensions.

  1. for (enumerators) yield e, where enumerators refers to a semicolon-separated list of enumerators
  2. An enumerator is either a generator which introduces new variables, or it is a filter.

12  [T]  generic

  1.  take a type as a parameter,useful for collection classes
  2. Stack[A] is only a subtype of Stack[B] if and only if B = A
  3. 以泛型作参
  4. trait Cache[K, V] {
      def get(key: K): V
      def put(key: K, value: V)
      def delete(key: K)
    }
    def remove[K](key: K)//方法中以泛型作参

13   +A -A A variance

  1. +A where A is a subtype of B, then List[A] is a subtype of List[B]
  2. -A where A is a subtype of BWriter[B] is a subtype of Writer[A].
  3. trait Function1[-T, +R]  T:argument type R:return type
  4. 需要注意的是,所有的类型信息会在编译时被删去,因为它已不再需要。这就是所谓的擦除。学术界一直很努力地提高类型系统的表现力,包括值依赖(value-dependent)类型!用程序将会退化为一系列类型转换(“asInstanceOf[]”),并且会缺乏类型安全的保障(因为这些都是动态的)。

    1. 在函数式编程语言中,类型推断的经典方法是 Hindley Milner算法,它最早是实现在ML中的。Scala类型推断系统的实现稍有不同,但本质类似:推断约束,并试图统一类型

    2. 有一些你想表达的类型概念“过于泛化”以至于编译器无法理解
  5. An upper type bound T <: A declares that type variable T refers to a subtype of type A

14  你并不关心是否能够命名一个类型变量,可以使用“通配符”取而代之。List[_]  相当于   List[ T forSome { type T } ]

 

15  The term B >: Aexpresses that the type parameter B or the abstract type B refer to a supertype of type A.

 def prepend(elem: B) = ListNode[B](elem, this

16  

17  

18  scala类中不带参数的方法和属性可以互相重写。

19  尾递归函数:指的是递归函数的递归语句在函数的最后一行,这种递归函数的执行速度和使用循环代替递归的速度是一样的,不会有任何额外开销。

20  import 可以重命名或者隐藏一些被引用的成员。

//只能访问ArrayBuffer 的 concat和newBuilder两个方法,其他方法被隐藏,并且给 concat加了个别名conc,你可以通过conc访问concat
import scala.collection.mutable.ArrayBuffer.{concat =>conc,newBuilder}
//可以访问除了newBuilder 外的所有成员
import scala.collection.mutable.ArrayBuffer.{newBuilder =>_,_} 

21  scala三引号的作用和python三引号的作用相同

22  嵌套类 若需要被嵌套的类的实例之间可沟通,需要在类中所需沟通用到的被嵌套类表示为:类名#被嵌套类名

23  插值:f s raw 

24  : 右结合

object Log { def >>:(data:String):Log.type = { println(data); Log } }
res0: "Hadoop" >>: "Spark" >>: Log

25  abstract class

  1. Traits and abstract classes can have an abstract type member.

26  exception

  1. 面向表达式
  2. 当一个异常被捕获处理了,finally块将被调用;它不是表达式的一部分。

27  Set & List & Tuple & Map & Option

  1. val numbers = List(1, 2, 3, 4)
  2. scala> Set(1, 1, 2)
    res0: scala.collection.immutable.Set[Int] = Set(1, 2)
  3. 元组是在不使用类的前提下,将元素组合起来形成简单的逻辑集合。元组不能通过名称获取字段,而是使用位置下标来读取对象;而且这个下标基于1,而不是基于0。
  4. 映射的值可以是映射或是函数

  5.  Option本身是泛型的,并且有两个子类: Some[T] 或 None。Map.get 使用 Option 作为其返回值,表示这个方法也许不会返回你请求的值。 如Map("one"->1).get("one"),这里返回  res0: Option[Int] = Some(1),为option的子类,若需要取值则get、getOrElse 用法见snippets

28  Functional Combinators

  1. List(1, 2, 3) map squared。foreach很像map,但没有返回值。foreach仅用于有副作用[side-effects]的函数。

  2. map对列表中的每个元素应用一个函数或传入一个部分应用函数(和_结合使用)。Map可以被看作是一个二元组的列表,所以你写的函数要处理一个键和值的二元组。

  3. filter移除任何对传入函数计算结果为false的元素。返回一个布尔值的函数通常被称为谓词函数[或判定函数]。
  4. zip将两个列表的内容聚合到一个对偶列表中。
  5. partition将使用给定的谓词函数分割列表。
  6. find返回集合中第一个匹配谓词函数的元素。
  7. drop 将删除前i个元素
  8. dropWhile 将删除元素直到找到第一个匹配谓词函数的元素。例如,如果我们在List(1,2,3)上使用dropWhile奇数的函数, 1将被丢弃(但3不会被丢弃,因为他被2“保护”了)。
  9. fold 见link
  10. flatten将嵌套结构扁平化为一个层次的集合。可以把flatMap看做是“先映射后扁平化”的快捷操作

 

29   compose & andThen

  1.  val fComposeG = f _ compose g _  : f(g(x))
  2. val fAndThenG = f _ andThen g _   : g(f(x))

30  PartialFunction

  1. 一个定义为(Int) => String 的偏函数可能不能接受所有Int值为输入。

    isDefinedAt 是PartialFunction的一个方法,用来确定PartialFunction是否能接受一个给定的参数。

  2. 偏函数PartialFunction 和我们前面提到的部分应用函数是无关的。
  3. case是PF函数的子类
  4. 可以使用orElse组成新的函数,得到的PartialFunction反映了是否对给定参数进行了定义。

 

posted on 2017-09-24 09:10  satyrs  阅读(196)  评论(0编辑  收藏  举报

导航