Scala笔记

1、伴生对象

形如:
有一个类
class Test{
}
一个object和该类同名
object Test{
}

object Test的作用类似于静态类(工具类),其中的所有成员都是静态的,在object Test中可以直接访问class Test的成员;反之,class Test中要通过object Test来引用其成员例如使用Test.的方式

2、apply方法

class中的apply:是一个比较特殊的方法,通过这个class new 出来的对象,可以直接通过对象(),这样的方式来调用apply方法

object中的apply:比较常用,例如,通常使用数组时是下面这样的代码:

val arr = new Array[Int](3)
arr(0) = 1
arr(1) = 2
arr(2) = 3

但是,在scala中可以通过伴生对象的apply方法,我们可以很方便的构建类的对象,而不必知道和操作这个过程,如下:

val arr = Array(1,2,3)

通过伴生对象的apply方法,我们可以很方便的构建类的对象,而不必知道和操作这个过程,在apply方法中其实也是new出一个Array,并在其中做好了初始化操作
源代码如下:

/** Creates an array of `Int` objects */// Subject to a compiler optimization in Cleanup, see above.def apply(x: Int, xs: Int*): Array[Int] = {val array = new Array[Int](xs.length + 1)array(0) = xvar i = 1for (x <- xs.iterator) { array(i) = x; i += 1 }array}

3、继承

没啥好说的,概念和其他语言一样,只是语法有点区别:

class Father(name:String){
...
}
//构造子类的时候会先构造父类,所以要将父类构造函数需要的参数给它
class Son(name:String,age:Int) extends Father(name){
...
}

4、trait特质

trait可以当接口来用,但是和其他语言的接口有些不同,trait里面竟然还可以有方法的定义!
那么这样和抽象类不是一样的了,干嘛还要trait?
Scala中也是单继承,也就是说一个类只能继承一个父类,需要有很多子类的特性的时候就可以通过继承多个trait来实现(可以把抽象类看成是一个统一的模板,trait则是其他七七八八的装饰,可加可减灵活性高)

在Scala中如果一个class,或者一个trait直接继承了另外一个trait,那么语法是一样的:

trait Test{
...
}class Test1 extends Test{
...
}

当多重继承时,trait要使用with关键字,构造顺序从左往右,且不重复构造:

class Human{...}
trait ITeacher extends Human{...}
trait IBasketballPlayer extends Human{...}
class BasketballTeacher extends Human with ITeacher with IBasketballPlayer{...}

由于ITeacher和IBasketballPlayer都继承了Human,理论上在构造他们的时候会去构造他们的父类,也就是Human,但是由于Human之间在构造BasketballTeacher 的时候已经构造过了,所以这里不再重复构造

上面代码演示的是在定义class的时候混入trait
实际上也可以在new object的时候使用,这样可以在具体的场景中定义具体处理的对象(和定义class的时候直接混入的区别是,前者new出来的所有object都带有trait特质的,后者只作用在一个单一的object):

class Human{...}
trait ITeacher extends Human{...}
trait IBasketballPlayer extends Human{...}val t1 = new Human with ITeacher with IBasketballPlayer{
//如果有抽象方法,在此重写
}

需要注意的是,混入的trait必须都继承自同一个父类

trait的AOP实现:

trait DoSomething {def work
}class Do extends DoSomething{override def work: Unit = {println("working!")}
}trait BeforeAndAfter extends DoSomething {abstract override def work: Unit = {println("init...")super.workprintln("destroy...")}
}object test {def main(args: Array[String]) {val worker = new Do with BeforeAndAfterworker.work}
}

上面的代码中,使用trait实现了一个简单的AOP编程实例

首先定义了一个trait DoSomething,里面有一个抽象方法work
class Do继承自DoSomething,并实现了具体的work方法

这时new一个Do的object之后调用work应该打印出一行记录
之后定义了另外一个trait BeforeAndAfter,也继承了DoSomething并重写work

在其重写的方法中将父trait的work方法放在初始化和销毁的操作之间,由于父trait的work方法是抽象的,此时又调用了这个抽象方法,所以这个重写的work仍然是抽象的,要加上abstract关键字

在new Do的object的时候混入这个trait就可以实现AOP,代码执行过程应该是这样的:
1、调用worker的work方法,由于混入了trait,所以实际调用的是这个trait里面的work
2、这个trait里面的work先进行了初始化操作,然后调用父trait的work,而这个方法的具体实现是在Do类中完成的,所以又调用了Do类中的具体work实现
3、work调用完成之后,进行销毁操作

5、包对象

包对象的定义及作用如下:

//这是一个包对象
package obejct Person{...}
//这是一个包的定义
package Person{
//此时,在这个包的作用于范围之内,可以直接访问包对象的成员
}//使用这种语法的import意思是将scala包中的StringBuilder隐藏起来不使用(使用别的包的StringBuilder)
import scala.{StringBuilder => _}

6、文件操作

//读取本地文件
val localFile = Source.fromFile("file path")
val lines = localFile.getLines
//读取网络文件
val networkFile = Source.fromURL("file url")
//创建一个写入器
val writer = new PrintWriter(new File("file path"))
writer.println("something to write")
writer.close
//控制台读取
Console.readLine

7、正则表达式

//可以直接使用字符串.r的方式返回一个Regex对象
val regex1 = "[0-9]+".r
//三个引号表示表达式中的符号都是原意,而不是转义符(如\)
val regex2 = """\s+[0-9]+\s+""".r
//Regex对象可以直接调用findAllIn/findFirstIn等方法
regex1.findAllIn("1234 dqd qwdq")//该方法会返回全部匹配项

正则表达式和模式匹配相结合

val regex = """([0-9]+) ([a-z]+)""".r
val line = "123 abc"
line match {
//line如果符合regex1规则,会将其自动匹配成(num,str)格式
case regex(num, str) => println(num + ":" + str)
case _ => println("~~~~~~~~~`")
}

8、内部函数的定义

开发过程中,经常将各个子功能定义为一个个函数,在通过一个统一入口函数在调用这个子函数
但是这样存在一个问题,入口函数和子函数通常是定义在一起的,既然入口函数可以被外部调用,那么子函数同样也可以
这就不是我们想要的效果了,我们需要实现的是外部只能调用入口函数,而对于其他的子功能都是不可见的
这也就是高内聚低耦合的思想

在Scala中,函数是一等公民,意味着函数可以当做变量成员来使用
那么,在函数中可以定义变量,也就可以定义函数
这就是内部函数

def portal{//内部函数定义def action1{}def action2{}...调用内部函数action1action2
}

9、闭包

简单的说,闭包就是指在一个函数中,能够访问另外一个函数的变量(必须要访问这个变量才能完成函数的工作),读取这个变量之后,这个函数就关闭执行,成为闭包
一个简单的闭包例子:

//这个函数中,要完成功能必须要知道more的值
def add(more:Int) = (x:Int) => x + more
//传入more的值为1,返回值其实还是一个函数x+1
val a = add(9)
val b = add(90)
//调用这个返回的函数,传入x=1
a(1)
b(10)

10、高阶函数

高阶函数简单的说就是 参数是函数 的函数
例如map、reduce等需要传入匿名函数的函数
具体操作就不详细说明了,因为高阶函数太多了= =使用方法都是差不多的

11、SAM转换

即Simple Abstract Method
在例如Java等语言中,代码通常是这样子写的:

jButton.addActionListener(new ActionListener{override def actionPerformed(event:ActionEvent){counter += 1}
})

jButton的addActionListener需要一个格式为(event:ActionEvent)=>Unit的方法,上面的代码中直接new出了一个ActionListener并重写其方法传入
这叫做样本代码,即符合这个样本格式的方法才能使用
而很多时候,addActionListener这类的方法并不需要知道这么多信息,它只需要我们给它一个方法就行了,而不是一大堆的重新new对象,重写方法

在Scala中是这么解决问题的:

//这是一个隐式转换,其实起到的作用就是样本代码,名字任意,只要参数和返回值是符合固定格式的即可
implicit def makeAction(action:(ActionEvent) => Unit) = {new ActionListener{override def actionPerformed(event:ActionEvent){action(event)}
}//有了上面的隐式转换,我们就可以很简洁的直接将方法当做参数传入
jButton.addActionListener((event:ActionEvent) => counter += 1)

此时,在这个界面的所有地方,都可以传入(ActionEvent) => Unit类型的函数给需要的函数了

总结SAM转换:
借助隐式转换,将样本代码省去
传入一个方法,自动扫描当前区域的隐式转换(定义了样本代码),如果转换成功就可以调用

12、Currying函数柯里化

函数的柯里化即将原来接受两个参数的函数变成新的接受一个参数的函数的过程。
简单的例子:

//多参数的函数
def add(x:Int,y:Int) = x + y
add(1,2)
//接受一个参数的函数
def add(x:Int) = (y:Int) => x + y
add(1)(2)

对于只接受一个参数的函数格式是不是挺熟悉的?在之前的闭包中使用的就是这种格式的函数
Scala中支持定义简介的柯里化函数

def add(x:Int)(y:Int) = x + y

柯里化的作用有很多,其中一个就是用来做类型推断
在一些场合,Scala编译器可以通过第一个参数的类型推荐第二个参数的类型以便进行一些操作

13、模式匹配

Scala的模式匹配类似于switch,但是更加灵活,格式如下:

val line = ...
line match{case ... => ......case _ => ...
}

每个case都有返回值(没有特殊指定的话)
case分支不用break
case后可以用常亮,变量,表达式,方法等

模式匹配还有很多其他的特殊的用法
例如:匹配type,array、list、tuple格式

def match_type(t:Any) = t match{case i:Int => println("Int")case s:String => println("String")case m:Map[_,_] => m.foreach(println)
}def match_array(arr:Any) = arr match{//数组中只有一个0的匹配成功case Array(0) => ...//数组中有任意的两个数匹配成功case Array(x,y) => ...//数组中第一个为0,还有任意多个元素的匹配成功case Array(0,_*) => ...
}def match_list(lst:Any) = lst match{//List中有一个0的匹配成功(Nil表示一个空的List,::运算符是从右至左运算的,表示空List加上一个0元素,即为只有一个0的List集合)case 0 :: Nil => ...//List中有任意的两个数匹配成功case x :: y :: Nil => ...//集合中第一个为0,还有任意多个元素的匹配成功(tail表示List中除了第一个元素外的所有元素)case 0 :: tail => ...
}

14、样例类和样例对象

通常在系统开发中,我们需要自己定义一些数据结构来进行统一的消息传递,例如经常使用的Model
在Scala中,使用样例类和样例对象来完成这个功能
定义的格式如下:

case class Person(...)
case object Person1(...)

15、嵌套的样例类和模式匹配结合

abstract class Item{...}
case class Book(name:String,price:Int) extends Item
//BookList中嵌套了一个Book的样例类
case class BookList(num:Int,books:Book*) extends Itemdef match_caseclass(item:Item) = item match{//匹配BookList,用占位符_代替的属性都不关心,只要Book的name属性case BookList(_,Book(name,_),_*) => ...//可以使用别名@Book的方式进行模式匹配,后面的方法体中可以使用别名直接操作case BookList(_,b1 @ Book(_,_),other @ _*) => ...
}

未完待续…

转载于:https://www.cnblogs.com/jchubby/p/5449381.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/273151.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

maven找到mysql 连接池_在Tomcat6.0+MySQL5.0环境下配置和使用数据库连接池

一&#xff0c;在Tomcat中配置连接池的JNDI首先到MySQL的网站上下载MySQL JDBC连接器放到%CATALINA_HOME%/lib目录下&#xff0c;在%CATALINA_HOME%/conf目录下找到context.xml&#xff0c;这个文件是全局的&#xff0c;如果想只对特定的应用使用可以编辑WEB-INF/context.xml文…

mysql将多个成绩放在一排_mysql巧用连表查询各科成绩前三名

下列是各表的详情&#xff0c;不想自己建表的同学可以直接copy code&#xff0c;数据随意。创建表成绩详情表&#xff1a;CREATE TABLE score (id int(10) NOT NULL AUTO_INCREMENT,subject_id int(10) DEFAULT NULL,student_id int(10) DEFAULT NULL,score float DEFAULT NULL…

Oracle 跨库 查询 复制表数据 分布式查询

方法一&#xff1a; 在眼下绝大部分数据库有分布式查询的须要。以下简单的介绍怎样在oracle中配置实现跨库訪问。比方如今有2个数据库服务器&#xff0c;安装了2个数据库。数据库server A和B。如今来实如今A库中訪问B的数据库。 第一步、配置Aserver端的tnsnames.ora文件&#…

java 匹配mysql按钮_使用Java在mysql查询中设置匹配函数

我有以下在java中查询(mysql)的摘录&#xff1a;queryGeral.append("FROM product p, fabricante_product fp, fabricante f, extensao e, product_autor pa ").append(" WHERE ").append("a.nome like ? AND ").append("p.cod_material …

LeetCode Contains Duplicate (判断重复元素)

题意&#xff1a; 如果所给序列的元素不是唯一的&#xff0c;则返回true&#xff0c;否则false。 思路&#xff1a; 哈希map解决。 1 class Solution {2 public:3 bool containsDuplicate(vector<int>& nums) {4 unordered_map<int,int> mapp;5 …

提高团队代码质量

近期看到一篇博客。大致的意思就是网管将原本混乱不堪的交换机整理整齐了&#xff0c;起初交换机是图2那样的&#xff0c;由于越来用的人越多&#xff0c;操作的人越来越多。终于成为了图1那个样子。这不禁让我想到了项目中的代码。原先在刚上线的时候谈不上是完美的&#xff0…

webrender 查看是否开启_想要体验极致顺滑的网页加载体验?手动开启Firefox WebRender渲染引擎...

昨天我们提到火狐浏览器最新稳定版Mozilla Firefox v67 版将面向部分用户开启WebRender渲染引擎测试。据火狐浏览器团队介绍当用户开启新的渲染引擎后 , 网页加载帧率能够从现有的 20FPS 直接提升到 60FPS。不过新的渲染引擎本身并不是用于加快网页的加载速度&#xff0c;而是…

NOIP201307货车运输

试题描述A 国有n座城市&#xff0c;编号从1到n&#xff0c;城市之间有m条双向道路。每一条道路对车辆都有重量限制&#xff0c;简称限重。现在有q辆货车在运输货物&#xff0c;司机们想知道每辆车在不超过车辆限重的情况下&#xff0c;最多能运多重的货物。输入第一行有两个用一…

knime如何连接mysql_knime怎么连接MySQL?

首先判断一下网络是否通&#xff1a;如果在局域网相同网段内那网络是通的&#xff0c;不同网段间需要看是否有做隔离&#xff0c;如果没有隔离&#xff0c;那就也是通的。测试方法可以用telnet 数据库IP 数据库端口号的方式探测一下 例如 telnet 192.168. 1.124 3306创建用户&a…

Asp.net Vnext IValueProvider

概述 本文已经同步到《Asp.net Vnext 系列教程 》中] IValueProvider 根据ValueProvider获取数据&#xff0c;在对数据进行绑定 代码实现 private class CustomValueProvider : IValueProvider{//判断否具有指定的前缀public Task<bool> ContainsPrefixAsync(string pref…

ECNUOJ 2615 会议安排

会议安排 Time Limit:1000MS Memory Limit:65536KBTotal Submit:451 Accepted:102 Description 科研人员与相关领域的国内外同行进行适时的接触与充分的交流&#xff0c;对于促进提高他们的科研业务水平&#xff0c;并及时掌握科研动态是十分必要而且重要的。ECNU为了走在科技…

Kafka架构设计:分布式发布订阅消息系统

【http://www.oschina.net/translate/kafka-design】&#xff08;较长&#xff1a;很详细的讲解&#xff09; 【我们为什么要搭建该系统】用作LinkedIn的活动流&#xff08;activity stream&#xff09;和运营数据处理管道&#xff08;pipeline&#xff09;的基础。作为多种类型…

拼团php开发逻辑思维罗振宇_2019罗胖罗振宇跨年演讲手动整理稿,看了两遍

2019罗胖罗振宇跨年演讲看了两遍&#xff0c;手动整理文档1.岁月不饶人&#xff0c;我们也没饶了岁月2.你有你的计划&#xff0c;原来这个世界另有计划&#xff0c;既然这个世界另有计划&#xff0c;我们就得重做计划3.做事的人和不做事的人4.宏观是我们必须忍受的&#xff0c;…

URLConnection

转载&#xff08;http://www.cnblogs.com/shyang--TechBlogs/archive/2011/03/21/1990525.html&#xff09; 关于URLConnection&#xff0c;网上很多回答都是对API的翻译&#xff0c;很崩溃&#xff0c;我是看了很多之后&#xff0c;然后看API才发现的。此后我会吸取教训&#…

java文件拷贝_Java实现文件拷贝的4种方法

第一种方法:古老的方式public static long forJava(File f1,File f2) throws Exception{long timenew Date().getTime();int length2097152;FileInputStream innew FileInputStream(f1);FileOutputStream outnew FileOutputStream(f2);byte[] buffernew byte[length];while(tru…

今夜的硬件之旅

6脚继电器&#xff1a; 汇科继电器HK4100F-DC6V-SHG ①3A触点切换能力 ②具有一组常开&#xff0c;一组转换触点形式 ③超小型&#xff0c;标准印刷制版引出脚 ④有塑封型 Outline&#xff08;L*W*H&#xff09;外形尺寸&#xff1a;15.510.511.8 Contact Date触电形式&#…

mp3 pcm java_Java mp3文件转pcm文件

Java mp3文件转pcm文件package cn.zpy.util;import java.io.File;import java.io.IOException;import javax.sound.sampled.AudioFileFormat;import javax.sound.sampled.AudioFormat;import javax.sound.sampled.AudioInputStream;import javax.sound.sampled.AudioSystem;imp…

有1~5000一组乱序数列,请使用伪代码对该数进行排列

先把1-5000组成一个数组 冒泡排序法 $arrarray(1,2,3,4,5,6,7,8,9.....5000); $totalcount($arr); For($i0;$i<$total;$i){ For($j0;$j<$total-1;$j){ If($arr[$j]>$arr[$j1]){ $tmp$arr[$i]; $arr[$j]$arr[$j1]; $arr[$j1]$tmp; } } } 快速排序法 $arrarray(1,2,3,4,…

java 类型转换方法_java数据类型转换的常见方法

public class Testfun {public static void main(String[] args) {// (一)跨Number父类的类型转换// 1、str转int > Integer.parseInt(s1)String s1 "19";int i2 Integer.parseInt(s1);// 数字str转化为对标的intSystem.out.println("i2" (i2));// 2…

json to java 在线_Json转Java对象 (全网最简版)

Json2Java(全网最简版)json字符串转Java对象,生成对应文件描述&特点简易的Json转Java工具,满足基本日常使用(特殊需求可自行增添,代码就一页)在网上找了好些个这类工具,不是只暴露iead插件就是复杂&没文档,于是自己写了个全网最简版Json2Javaonly one file用法public c…