随笔分类 - scala
摘要:在Java中是可以使用变长参数的,如下面的方法: public void check(String ... args){ for(String tmp : args){ System.out.println(tmp); } } 在scala中也可以使用变长参数。和java一样,也是只有最后一个参数可以接收可变长度的参数。使用方式是在...
阅读全文
摘要:除了推演变量的类型,scala也会推演方法的返回类型。不过这里有一处需要注意:方法返回类型的推演依赖于方法的定义方式。如果用等号“=”定义方法,scala就会推演方法返回类型;否则,它就认为方法的返回为void。看一个例子: def printMethodInfo(methodName: String) { println("The return type of " + methodName ...
阅读全文
摘要:看到Option类型就知道这本教材应该要说那个了。 使用过guava后,应该知道guava中的Optional类的作用是什么。算了找下原始文档好了: Optional is a way of replacing a nullable T reference with a non-null value. An Optional may either contain a non-null T ref...
阅读全文
摘要:Any 前面已经有两次提到过:在scala中,Any类是所有类的超类。 Any有两个子类:AnyVal和AnyRef。对应Java直接类型的scala封装类,如Int、Double等,AnyVal是它们的基类;对应引用类型,AnyRef是它们的基类。 scala中,所有类的关系可以用下面这张图大致描述下: Any是一个抽象类,它有如下方法:!=()、==()、asInstanceOf()、equ...
阅读全文
摘要:关于scala的类型推断前面已经提到过多次。再来看一下下面这个例子: import java.util._ var list1: List[Int] = new ArrayList[Int] var list2 = new ArrayList[Int] list2 add 1 list2 add 2 var total = 0 for (index <- 0 until list2.size()...
阅读全文
摘要:前面两节学了scala的对象和伴生对象,这两个在使用的时候很有些java的静态成员的意思。 scala中没有静态字段和静态方法。静态成员会破坏scala所支持的完整的面向对象模型。不过可以通过伴生对象实现对scala的类一级的操作。 回过头来再看一遍那个Marker的例子,略做了一些调整: class Marker private(val color: String) { println("C...
阅读全文
摘要:上一节中的单例对象MarkerFactory 就是一个独立对象的例子。尽管它管理着Marker类,但是它并没有关联到任何类上。 scala也可以创建关联到类上的对象。这样的对象同类共享同一个名字,这样的对象称为伴生对象,对应的类就称为伴生类。在scala里,类和伴生对象没有界限,它们互相可以访问彼此的private 方法和private 属性。下面使用伴生对象重写了Marker: class Ma...
阅读全文
摘要:java中的单例模式都很熟悉了:简单地说就是一个类只能有一个实例。在scala中创建单例对象非常简单,创建类时使用object关键字替换class即可。因为单例类无法初始化,所以不能向它的主构造函数传递参数。 下面是一个单例的示例: class Marker(val color: String) { println("Creating " + this) override def to...
阅读全文
摘要:在scala里,类继承有两点限制: 重写方法需要使用override关键字; 只有主构造函数才能往父类构造函数中传参数。 在java1.5中引入了override注解,但不强制使用。不过在scala中要想重写方法必须使用override关键字。如果确实重写了父类的方法又不使用override关键字的话,则会在编译时报错,提示没有使用override修饰符。 scala的副构造函数必须调用主构造函...
阅读全文
摘要:在上一节创建了一个scala类,如果没有更多的方法,scala类的定义还可以更简单一些,看一下下面这个CreditCard类的定义: class CreditCard(val number: Int, var creditLimit: Int) 是的,只用一行就完成了类的定义,连大括号都不需要。 因为scala也是运行在JVM上,可以考虑以java的方式来看看编译后的类文件。查看的方式还是比较灵活...
阅读全文
摘要:这里会通过与Java比较的方式来说明scala是如何创建类的。 先来看一下Java中是如何定义一个类的: public class Car { private final int year; private int miles; public Car(int yearOfMake) { year = yearOfMake; } ...
阅读全文
摘要:scala的访问修饰符有如下几个特性: 如果不指定访问修饰符,scala默认为public; 较之Java,scala对protected的定义更加严格; scala可以对可见性进行细粒度的控制。 scala的默认访问修饰符 如果没有修饰符,scala会默认把类、字段、方法的访问修饰符当做public。如果要将之调整为private或protected,只需在前面添加对应的修饰符关键字即可。...
阅读全文
摘要:= 赋值运算 scala的赋值运算和java的有着很大的不同。如a=b这样的赋值运算,在Java中返回值是a的值,在scala中返回的则是Unit(Unit是值类型,全局只存在唯一的值,即(),通常Unit只用来声明函数或方法的返回值,其他场景基本是没有意义的)。这样就很容易导致一些错误地使用,比如a=b=c这样的赋值运算在java中是绝对可以的,但是在scala中运行就会报错。看一段代码: va...
阅读全文
摘要:scala有一些默认做法,会让代码更简洁、更易读写,下面列出了这样几个特性: 1. 支持脚本。scala支持脚本,因此无须将所有的代码都放到类里。如果脚本可以满足需求,就将代码放到一个脚本里,无须再创建一个冗余的类。 2. return是可选的。如果没有写return关键字,方法调用会自动返回最后一个求值的表达式——如果它符合方法声明的返回值类型。 3. 分号“;”是可选的。不必在每个语句的后面都...
阅读全文
摘要:从语法上来说scala是没有运算符的。之前的一节里也曾提到过scala的运算符实际上是方法名,如1 + 2实际上就是1.+(2)。我们可以将之视为运算符,是因为scala的一个特性:如果方法的参数小于等于1个的话,那么“.”和括号就都是可选的。 scala的运算符重载指的就是重载+、-这样的符号——和C、java或者python等语言不一样,我们需要自己定义这些符号如何实现。 下面看一个“+”运算...
阅读全文
摘要:scala中的字符串类就是java中的java.lang.String类。不过scala也为String提供了一个富封装类:scala.runtime.RichString。 scala可以将java.lang.String类自动转换为scala.runtime.RichString类。这样就可以非常方便地使用capitalize()、lines()和reverse()等方法相对较便捷的方法(有时...
阅读全文
摘要:假定要在一个方法中返回多个值。比如需要返回一个人的名、姓和邮箱地址。在Java中最常用的方法是定义一个Person类,其中包括相对应的字段;还有些不常用的方法就是返回一个集合或数组,拿到结果后再进行循环取值。在Scala中我们又多一个选择:元组。 元组是一个不可变的对象序列,可以使用逗号分隔的值进行创建,比如这个有3个对象的元组:(“robin”, “zhang”, “robin@zhyea.co...
阅读全文
摘要:在Java中变量类型分为两大类:基本类型和引用类型。虽然在JDK1.5以后引入了自动装箱和自动拆箱机制,大大减少了我们在直接类型和引用类型之间的纠结,但仍有一些我们不得不考虑的问题。比如我在工作遇到的基本类型和其包装类型的默认值的问题,比如泛型只能使用引用类型,比如默认情况下直接类型的值不能作为对象来操作(1.toString()就不能通过编译)等等。 在scala中一切都是对象。 在scala中...
阅读全文
摘要:scala中用var和val定义变量都是可以的。 用val定义的变量是不可变的,被初始化后值就固定下来,不可以再被修改(这类似于java中的final关键字);用var定义的变量是可变的,可以任意修改。 仍然要注意这里说的不可变是针对变量本身而言,而非变量所指向的实例。比如说如果定义了一个StringBuffer的val变量如val buffer = new StringBuffer(),那么变量...
阅读全文
摘要:先来看一段Java中的循环: for (int i = 1; i print(i + ",")) foreach是Range类的一个方法,这方法以一个函数值作为参数。所以要在括号里提供一段函数代码接受一个实参。在这个例子里,实参就是i。箭头“=>”的作用是将左边的参数列表和右侧函数实现分割开来。
阅读全文