除了推演变量的类型,scala也会推演方法的返回类型.不过这里有一处需要注意:方法返回类型的推演依赖于方法的定义方式.如果用等号"="定义方法,scala就会推演方法返回类型:否则,它就认为方法的返回为void.看一个例子: def printMethodInfo(methodName: String) { println("The return type of " + methodName + " is " + getClass().getDe…
关于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()) { total += list2.get(index) } println("Total i…
方法命名约定 之前在学习<运算符重载>一节时曾经说过一个方法命名约定:方法的第一个字符决定了方法的优先级.现在再说另一个命名约定:如果方法以冒号(:)结尾,则调用目标是运算符后面的实例. 比如下面这个例子: class Cow { def ^(moon: Moon) = println("Cow jumped over the moon") } class Moon { def ^:(cow: Cow) = println("This cow jumped ove…
在Java中变量类型分为两大类:基本类型和引用类型.虽然在JDK1.5以后引入了自动装箱和自动拆箱机制,大大减少了我们在直接类型和引用类型之间的纠结,但仍有一些我们不得不考虑的问题.比如我在工作遇到的基本类型和其包装类型的默认值的问题,比如泛型只能使用引用类型,比如默认情况下直接类型的值不能作为对象来操作(1.toString()就不能通过编译)等等. 在scala中一切都是对象. 在scala中1.toString()这样的写法是完全可以接受的.java中的每个基本类型在scala中都有对应的…
难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java第五十八章:多态中方法返回类型可以是子类类型 下一章 "全栈2019"Java第五十九章:抽象类与抽象方法详解 学习小组 加入同步学习小组,共同交流与进步. 方式一:关注头条号Gorhaf,私信"Java学习小组". 方式二:关注公众号Gorhaf,回复"Jav…
scala的一个最主要的特性就是支持函数编程.函数是函数编程中的一等公民:函数可以作为参数传递给其他函数,可以作为其他函数的返回值,甚至可以在其它函数中嵌套.这些高阶函数称为函数值. 举一个简单的例子:从1到某个数求和.使用Java很容易实现: int sum(int max){ int result = 0; for (int i = 0; i <= max; i++) { result +=i; } return result; } 使用scala实现也没有多大区别. 现在再扩展下需求:对某…
= 赋值运算 scala的赋值运算和java的有着很大的不同.如a=b这样的赋值运算,在Java中返回值是a的值,在scala中返回的则是Unit(Unit是值类型,全局只存在唯一的值,即(),通常Unit只用来声明函数或方法的返回值,其他场景基本是没有意义的).这样就很容易导致一些错误地使用,比如a=b=c这样的赋值运算在java中是绝对可以的,但是在scala中运行就会报错.看一段代码: var a, b, c = 1 a = b=c println(a) 上面这段代码还没有执行就在IDE中…
假定要在一个方法中返回多个值.比如需要返回一个人的名.姓和邮箱地址.在Java中最常用的方法是定义一个Person类,其中包括相对应的字段:还有些不常用的方法就是返回一个集合或数组,拿到结果后再进行循环取值.在Scala中我们又多一个选择:元组. 元组是一个不可变的对象序列,可以使用逗号分隔的值进行创建,比如这个有3个对象的元组:("robin", "zhang", "robin@zhyea.com"). 元组的一个特性就是多重赋值,就是可以将元…
在Scala里,下划线(_)可以表示函数值的参数.如果某个参数在函数里仅使用一次,就可以用下划线表示.每次在函数里用下划线,都表示随后的参数. val arr = Array(1, 2, 3, 4, 5) println("Sum of all values in array is " + (0 /: arr) { (sum, elem) => sum + elem }) 上面的代码里使用了"/:"方法.这个方法的意思大致上是从数组的左侧开始迭代运算.这里是用…
先来看一段Java中的循环: for (int i = 1; i < 4; i++) { System.out.print(i + ","); } 毫无疑问,scala可以让这个循环更加简洁.根据上一节中的内容,没有必要显示指定变量i的类型,我们甚至不需要声明这个变量.其次输出的语句也可以更加简洁一些,在scala中可以直接使用println()这个方法输出字符串.最后scala的循环结构也是非常的轻量级.好了,可以看一下代码了: for (i <- 1 to 3) { p…
前面两节学了scala的对象和伴生对象,这两个在使用的时候很有些java的静态成员的意思. scala中没有静态字段和静态方法.静态成员会破坏scala所支持的完整的面向对象模型.不过可以通过伴生对象实现对scala的类一级的操作. 回过头来再看一遍那个Marker的例子,略做了一些调整: class Marker private(val color: String) { println("Creating " + this) override def toString(): Stri…
在java中有switch/case这样的模式匹配语句,可以匹配的类型包括int,byte,char,short, enum,在java8又支持了字符串. 在scala中也有类似的模式匹配语句,即match-case.这个好现在之前使用过一次.scala中的match-case匹配的类型更为广泛,它是对Any类型起作用的. 来看个例子: def activity(day: String) { day match { case "Sunday" => println("E…
看到Option类型就知道这本教材应该要说那个了. 使用过guava后,应该知道guava中的Optional类的作用是什么.算了找下原始文档好了: Optional<T> is a way of replacing a nullable T reference with a non-null value. An Optional may either contain a non-null T reference (in which case we say the reference is &…
trait的方法的延迟绑定就是先混入的trait的方法会后调用.这一点从上一节的实例中也可以看出来. 下面再来看一个类似的例子: abstract class Writer { def write(message: String): String } trait UpperWriter extends Writer { abstract override def write(message: String): String = super.write(message.toUpperCase) }…
在上一节创建了一个scala类,如果没有更多的方法,scala类的定义还可以更简单一些,看一下下面这个CreditCard类的定义: class CreditCard(val number: Int, var creditLimit: Int) 是的,只用一行就完成了类的定义,连大括号都不需要. 因为scala也是运行在JVM上,可以考虑以java的方式来看看编译后的类文件.查看的方式还是比较灵活的,可以使用JD-GUI,也可以使用javap –private CreditCard命令,还有一个…
scala有一些默认做法,会让代码更简洁.更易读写,下面列出了这样几个特性: 1. 支持脚本.scala支持脚本,因此无须将所有的代码都放到类里.如果脚本可以满足需求,就将代码放到一个脚本里,无须再创建一个冗余的类. 2. return是可选的.如果没有写return关键字,方法调用会自动返回最后一个求值的表达式--如果它符合方法声明的返回值类型. 3. 分号":"是可选的.不必在每个语句的后面都写上分号,这样会使代码更简洁.如果语句太长或者包含多行的话可以换行继续写,scala能够识…
又重新开始了scala的学习,因为中断了太长时间,所以这次还得从零开始.学习的过程就记录在这个博客上了. 这次学习的教程是<scala程序设计 java虚拟机多核编程实战>,我在多看上买了电子书. 安装好了scala运行环境以后,先在命令行窗口来一次初体验.在命令行窗口输入如下命令: val number = 7 执行结果如下图: 我们在命令中并没有指明变量number的类型,但是并令执行后scala根据变量的值推断出了变量的类型,所以输出了number:Int = 6这样的信息. 在上面的使…
1.介绍 Scala 有方法与函数,二者在语义上的区别很小.Scala 方法是类的一部分,而函数是一个对象可以赋值给一个变量.换句话来说在类中定义的函数即是方法. Scala 中的方法跟 Java 的类似,方法是组成类的一部分. Scala 中的函数则是一个完整的对象,Scala 中的函数其实就是继承了 Trait 的类的对象. Scala 中使用 val 语句可以定义函数,def 语句定义方法. 2.实例代码 object Test1 { //定义一个方法 //方法method_test参数要…
这次统一看一下scala中容器类的几个方法. Set filter()方法 filter()方法用来从Set中过滤获取含有指定特征的元素.示例代码如下: val colors1 = Set("Blue", "Green", "Red", "yellow") val filteredSet = colors1 filter (_ contains "l") println(filteredSet mkStri…
控制器公开控制器操作.操作是控制器上的方法,在浏览器的地址栏中输入特定 URL 时被调用.例如,假设要请求下面的 URL: http://localhost/Product/Index/3 在这种情况下,调用 ProductController 类上的 Index() 方法.Index() 方法是控制器操作的一个示例. 控制器操作必须是控制器类的公共方法.默认情况下,C# 方法是私有方法.请注意,任何添加到控制器类的公共方法都自动公开为控制器操作(必须小心对待这个问题,因为任何人都可以简单地通过…
先来看一下下面的内容: 2 days "ago" 5 days "from_now" 如上的内容具体应该是什么呢?不过怎么看也不像是代码.不过既然是在学代码,拿不是代码的东西出来做什么! 非要强说是代码的话,那么执行起来肯定是要报错的--因为scala的Int和RichInt,以及Integer中都没有days这样的方法: 如果说不是代码的话,那么scala中的to或until本来看起来也不像代码: 2 to 6 2 until 7 现在剩下的就是怎么为整型值添加上…
我们访问资源需要关注对资源的锁定.对资源的申请和释放,还有考虑可能遇到的各种异常.这些事项本身与代码的逻辑操作无关,但我们不能遗漏.也就是说进入方法时获取资源,退出方法时释放资源.这种处理就进入了Execute Around模式的范畴. 在scala里可以用函数值实现这种模式.下面是一个示例,使用Resource类演示了事务的开启和释放: class Resource private() { println("Starting transaction...") private def…
函数值对消除代码重复有很大的帮助.但是像函数值这样直接将一个函数作为另一个函数的参数却不太利于函数值本身的重用. 来看一个例子: class Equipment(val routine: Int => Int) { def simulate(input: Int) = { print("Running simulation...") routine(input) } } 在这个例子里将函数值作为参数传到了构造器中. 看一下如何使用: val equipment1 = new Eq…
curry翻译为中文就是咖喱.意为使用curry可以让代码更有味道. scala里的curry化可以把函数从接收多个参数转换成接收多个参数列表.也就是说我们要编写的函数不是只有一个参数列表,这个参数列表中有多个参数以逗号分隔:而是一个函数中有多个参数列表,每个参数列表中只有一个参数(当然,也可以有多个参数).也就是说我们写的函数不再只是这样子的: def foo(a: Int, b: Int, c: Int) {} 而是这样子的:foo(1)(2)(3),或者这样的:foo(1){2}{3},甚…
上一节的函数值只有一个参数.函数值当然也是可以有多个参数的.看一下下面的inject方法: def inject(arr: Array[Int], initial: Int, operation: (Int, Int) => Int): Int = { var carryOver = initial arr.foreach(element => carryOver = operation(carryOver, element)) carryOver } 在inject方法中有三个参数:一个数组…
java 的代码中多少有些不是很严谨的内容,比如下面的这段代码: public class Trouble { public static void main(String[] args) { Integer[] arr1 = new Integer[2]; arr1[0] = new Integer(1); Object[] arr2 = arr1; arr2[1] = new Double(2.0); for (Integer i : arr1) { System.out.println(i…
在Java中是可以使用变长参数的,如下面的方法: public void check(String ... args){ for(String tmp : args){ System.out.println(tmp); } } 在scala中也可以使用变长参数.和java一样,也是只有最后一个参数可以接收可变长度的参数.使用方式是在参数类型后使用特殊符号"*",如下面的max()方法: def max(values: Int*) = values.foldLeft(values(0))…
Any 前面已经有两次提到过:在scala中,Any类是所有类的超类. Any有两个子类:AnyVal和AnyRef.对应Java直接类型的scala封装类,如Int.Double等,AnyVal是它们的基类:对应引用类型,AnyRef是它们的基类. scala中,所有类的关系可以用下面这张图大致描述下: Any是一个抽象类,它有如下方法:!=().==().asInstanceOf().equals().hashCode().isInstanceOf()和toString().AnyVal没有…
scala的访问修饰符有如下几个特性: 如果不指定访问修饰符,scala默认为public: 较之Java,scala对protected的定义更加严格: scala可以对可见性进行细粒度的控制. scala的默认访问修饰符 如果没有修饰符,scala会默认把类.字段.方法的访问修饰符当做public.如果要将之调整为private或protected,只需在前面添加对应的修饰符关键字即可.就如下面的程序: class Microwave{ def start() = println("star…
scala中的字符串类就是java中的java.lang.String类.不过scala也为String提供了一个富封装类:scala.runtime.RichString. scala可以将java.lang.String类自动转换为scala.runtime.RichString类.这样就可以非常方便地使用capitalize().lines()和reverse()等方法相对较便捷的方法(有时候这样做也会带来一些问题,比如涉及到类型比较的时候). 在scala里,对于字符串的支持中最显著的一…