{"id":18996612,"url":"https://github.com/vonzhou/scalaimpatient","last_synced_at":"2026-04-16T14:30:20.625Z","repository":{"id":81368257,"uuid":"162771039","full_name":"vonzhou/ScalaImpatient","owner":"vonzhou","description":"Scala for the Impatient 《快学Scala》第一版习题代码","archived":false,"fork":false,"pushed_at":"2019-01-31T15:33:49.000Z","size":52,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-01-01T16:43:12.239Z","etag":null,"topics":["functional-programming","scala"],"latest_commit_sha":null,"homepage":"http://vonzhou.com","language":"Scala","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/vonzhou.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2018-12-22T01:06:24.000Z","updated_at":"2022-08-31T16:11:55.000Z","dependencies_parsed_at":null,"dependency_job_id":"af7aea1b-fecc-4452-b307-548d710f0a12","html_url":"https://github.com/vonzhou/ScalaImpatient","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vonzhou%2FScalaImpatient","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vonzhou%2FScalaImpatient/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vonzhou%2FScalaImpatient/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vonzhou%2FScalaImpatient/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/vonzhou","download_url":"https://codeload.github.com/vonzhou/ScalaImpatient/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":240011333,"owners_count":19733683,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["functional-programming","scala"],"created_at":"2024-11-08T17:36:07.057Z","updated_at":"2026-04-16T14:30:18.546Z","avatar_url":"https://github.com/vonzhou.png","language":"Scala","funding_links":[],"categories":[],"sub_categories":[],"readme":"[主页](http://vonzhou.com)  | [读书](https://github.com/vonzhou/readings)  | [知乎](https://www.zhihu.com/people/vonzhou) | [GitHub](https://github.com/vonzhou)\n---\n# 《快学Scala》读书笔记\n---\n\n这本书我是2013年买的，当时看了一部分，然后又忘了，现在重新阅读。\n\nScala将OOP和函数式编程有机结合，动静兼备。前面的基本招式通读后，基本上可以理解。但是后面的类型系统，协变型变，定界延续目前还搞不懂，暂时略过。\n\n\n## 1.基础\n\nScala解释器的使用。\n\nval,var声明值和变量。\n\n有7中数值类型：Byte,Char,Short,Int,Long,Float,Double,Boolean，和Java不同的是这些都是类。\n\nScala中使用方法进行数值类型的转换，而不是强制类型转换。\n\n和`Java，C++`不同的是，Scala中没有++,--操作符，要使用+=1。\n\n`()`操作符背后的实现原理是`apply`方法。\n\n\n## 2.控制结构和函数\n\nif表达式有值。\n\n{}块也有值，值是最后一个表达式的值。这个特性对于要分多步来初始化val的情况很有用。\n\n\nUnit等同于Java，C++中的void。\n\n赋值语句本身没有值，是Unit。\n\n定义函数的时候，最好不使用return。\n\nScala中没有Checked Exception。\n\n\n\n## 3.数组相关操作\n\n定长数组是Array, 变长数组是ArrayBuffer。\n\n用 `for(e \u003c- arr)` 遍历元素。\n\n用 `for(e \u003c- arr if ...) yield ...` 转换数组。\n\nScala数组和Java数组互操作。\n\n## 4.映射和元组\n\nScala中没有可变的树形映射，可以选择Java的TreeMap。\n\n元组可以用于函数需要返回不止一个值的情况。\n\n## 5.类\n\nScala为每个字段生成`getter，setter`方法，不过可以通过`private,val,var,private[this]`控制这个过程。\n\n如果需要JavaBeans版的`getter，setter`方法，可以使用BeanProperty注解。\n\nScala中类有一个主构造器（primary constructor），任意多个辅助构造器（auxiliary constructor），名称是this。每个辅助构造器都必须开始于调用其他辅助构造器或者主构造器。\n\n\n练习5.注意BeanProperty包路径变了，`scala.beans.BeanProperty`。\n\n```java\n➜  ch05 git:(master) scalac Student.scala\n➜  ch05 git:(master) javap -private Student\nCompiled from \"Student.scala\"\npublic class Student {\n  private java.lang.String name;\n  private long id;\n  public java.lang.String name();\n  public void name_$eq(java.lang.String);\n  public void setName(java.lang.String);\n  public long id();\n  public void id_$eq(long);\n  public void setId(long);\n  public java.lang.String getName();\n  public long getId();\n  public Student(java.lang.String, long);\n}\n```\n\n## 6.对象\n\n在Java中会使用单例对象的地方，Scala中用对象，单例模式。\n\n搞清类和伴生对象（companion object）的关系。\n\n定义枚举的方法。\n\n## 7.包和引入\n\n包对象（package object）。\n\n可以在任何地方声明包引入。\n\n\n\n## 8.继承\n\n要知道Scala的继承层级。\n\n能看懂，但是自己怕是写不出来，需要练习。\n\n\n## 9.文件和正则表达式\n\n用完Source对象，要记得close。\n\n如果要查看某个字符，但是不处理掉它，使用source.buffered方法（类似C++中的`istream::peek`，或java中的`PushbackInputStream`）。\n\nScala没有提供读取二进制文件的方法，要使用java类库。写文件也要使用java库`java.io.PrintWriter`。\n\n可以编写shell脚本。\n\n## 10.特质\n\nScala和Java不能多重继承（菱形继承问题）。\n\n特质可以同时拥有抽象方法和具体方法，类可以实现多个特质。\n\n实现特质用的extends，而不是implements，实现多个特质用with（奇怪么? `extends A with B`，`A with B`先是一个整体，然后由类扩展）。所有Java接口都可作为Scala的trait使用。\n\n注意引入特质后，类的构造器执行顺序。\n\n\n特质不能有构造器参数。\n\n\n自身类型（self type）可以解决特质间的循环依赖。\n\n\n## 11.操作符\n\n操作符的优先级。\n\napply, update可以简化方法的调用。\n\nunapply，unapplySeq和模式匹配的关系。\n\n## 12.高阶函数\n\n函数是一等公民。\n\n## 13.集合\n\n\n所有集合都扩展自Iterable trait。\n\nJava中ArrayList和LinkedList实现了共同的List接口，使得编写要考虑随机访问效率的代码比较困难，后来加入的RandomAccess（1.4）就是应对这个的。\n\nScala优先采用不可变集合。\n\n\n\n## 14.模式匹配和样例类\n\nScala中模式匹配match无需在每个分支后面break。\n\n支持守卫，而无需把每种情况的case都列出来。\n\n倾向于使用类型模式匹配，而不是isInstanceOf操作符。匹配发生在运行时，所以泛型会擦除。\n\n模式匹配用于数组，列表，元组背后是提取器机制，对应的伴生对象实现unapply，unapplySeq方法。比如Array的：\n\n```scala\n/** Called in a pattern match like `{ case Array(x,y,z) =\u003e println('3 elements')}`.\n   *\n   *  @param x the selector value\n   *  @return  sequence wrapped in a [[scala.Some]], if `x` is a Seq, otherwise `None`\n   */\n  def unapplySeq[T](x: Array[T]): Option[IndexedSeq[T]] =\n    if (x == null) None else Some(x.toIndexedSeq)\n    // !!! the null check should to be necessary, but without it 2241 fails. Seems to be a bug\n    // in pattern matcher.  @PP: I noted in #4364 I think the behavior is correct.\n```\n\n\n样例类（`Case Class`）的使用场景和作用。List就是用样例类实现的。\n\n\n推荐使用Option表示可有可无的东西。\n\n## 15.注解\n\n\nAnnotation，StaticAnnotation, ClassfileAnnotation。\n\n\n## 17.类型参数\n\n类型变量界定，上界`\u003c:`，下界`\u003e:`。\n\n视图界定`\u003c%`，表示可以隐式转换的情况。\n\n要实例化一个`Array[T]`,需要一个`Manifest[T]`对象，这么复杂？因为JVM中泛型擦除。\n\n\n\u003e 读于 2018.12.29 杭州","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvonzhou%2Fscalaimpatient","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fvonzhou%2Fscalaimpatient","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvonzhou%2Fscalaimpatient/lists"}