Scala
特性
面向对象特性
Scala是一种纯面向对象的语言,每个值都是对象。对象的数据类型以及行为由类和特质描述。
函数式编程
Scala也是一种函数式语言,其函数也能当成值来使用。Scala提供了轻量级的语法用以定义匿名函数,支持高阶函数,允许嵌套多层函数,并支持柯里化。Scala的case class及其内置的模式匹配相当于函数式编程语言中常用的代数类型。
静态类型
Scala具备类型系统,通过编译时检查,保证代码的安全性和一致性
扩展性
Scala提供了许多独特的语言机制,可以以库的形式轻易无缝添加新的语言结构:
- 任何方法可用作前缀或后缀操作符
- 可以根据预期类型自动构造闭包
并发性
Scala使用Actor作为其并发模型,Actor是类似线程的实体,通过邮箱发收消息。Actor可以复用线程,因此可以在程序中可以使用数百万个Actor
基础语法
关键字
在scala中不能使用以上关键字作为变量
换行符
scala是面向行的语言,语句可以用分号(;)结束或换行
scala程序里语句末尾的分号通常是可选的
scala包
使用package关键字定义包
使用import关键字引用包
数据类型
scala与java有着相同的数据类型
下列数据类型都是对象,在scala中可以对数字等基础类型调用方法的
多行字符串使用三个双引号表示分隔符,格式为(""" … “”")
变量
在scala中,使用var定义变量,使用val定义常量
//变量申明
//varName:变量名 DataType:数据类型 Initial Value:初始值
var varName:DataType[=Initial Value]
//常量声明
val varName:DataType[=Initial Value]
声明变量时,若不指定数据类型,就需要给出初始值(数据类型可以通过初始值推断出来)
访问修饰符
默认情况下Scala对象访问级别是public
private
在嵌套类情况下,外层类甚至不能访问被嵌套类的私有成员
用private关键字修饰,带有此标记的成员仅在包含成员定义的类或对象内部可见
class Outer{
class Inner{
private def f(){
println("f function")
}
class InnerMost{
f() //能正确访问
}
}
(new Inner).f() //错误访问
}
因为f()方法在Inner类中被声明为private,而 (new Inner).f()访问在Inner类之外,所以访问不合法
protect
只允许保护成员在定义了该成员的类的子类中被访问
package p{
class Super{
protected def f() {println("f")}
}
class Sub extends Super{
f() //正确
}
class Other{
(new Super).f() //错误
}
}
public
scala中默认访问修饰符为public,这样的成员在任何地方都可以被访问
class Outer {
class Inner {
def f() { println("f") }
class InnerMost {
f() // 正确
}
}
(new Inner).f() // 正确因为 f() 是 public
}
方法与函数
scala中方法和java定义类似,是组成类的一部分
scala中的函数是一个对象可以赋值给一个白能量,函数则是一个完整的对象,其实就是继承了Trait的类的对象
scala中使用val语句定义函数,使用def语句定义方法
class Test{
def m(x:Int) = x + 3
val f = (x:Int) => x + 3
}
方法声明:
def function([参数列表]) : [return type]
如果方法后没有等号和方法体,该方法被隐式声明为抽象(abstract)
方法定义:
使用def关键字,紧接着是可选的参数列表,一个冒号和方法的返回类型,一个等号,最后是方法的主体
//return type可以是任意合法的scala数据类型
//参数列表中的参数可以使用逗号分隔
def function([参数列表]) : [return type] ={
function body
return [expr]
}
//将两个传入的参数相加并求和
object Add{
def addInt(a:Int,b:Int):Int ={
var sum:Int = 0
sum = a + b
return sum
}
}
如果方法没有返回值,可以返回Unit(和Java的void类似)
object Hello{
def sayHello:Unit={
println("hello scala")
}
}
可变参数
通过在参数的类型之后放一个星号来设置可变参数(参数类型一致)
def printString(args:String*)={
var i:Int = 0
for(arg <- args){
println("arg value["+i+"]="+arg)
i = i +1
}
}
默认参数
在未传递参数时,函数会调用默认参数值,若传递参数则传递值会取代默认值
object Test{
def main(args:Array[String]){
//调用方法时未传递参数,使用默认值
println("返回值为"+addInt())
}
def addInt(a:Int=5,b:Int=6):Int={
var sum = 0
sum = a + b
return sum
}
}
//执行结果=》返回值为11
当函数同时包含普通参数和默认参数时,无默认参数的在前,默认参数在后
def defaultAddInt(c:Int,a:Int=5,b:Int=6):Int={
function body
}
递归函数
函数可以调用它本身
object Test{
def main(args:Array[String]){
for(i <- 1 to 10){
println(i+"的阶乘为:"+factorial(i))
}
}
def factorial(n:BigInt):BigInt={
if(n <= 1)
1
else
n * factorial(n-1)
}
}
匿名函数
定义:箭头左边是参数列表,右边是函数体
//定义一个接受Int类型输入参数的匿名函数
var inc = (x:Int) => x+1
//此时inc可作为一个函数被调用
var x = inc(7)-1
//无参数的匿名函数
var userDir = () => {println("scala")}
闭包
闭包是一个函数,返回值依赖于声明在函数外部的一个或多个变量
通常来讲,可以简单认为是访问一个函数里面局部变量的另外一个函数
object Test{
def main(args:Array[String]){
println( "muliplier(1) value = " + multiplier(1) )
println( "muliplier(2) value = " + multiplier(2) )
}
//自由变量,定义在函数外面
var factor = 3
//muliplier引用到函数外面定义的变量,成为一个“闭包”
val muliplier = (i:Int) => i * factor
}
字符串
在scala中,字符串的类型实际上是 Java String
在scala中,String是一个不可变的对象,所以该对象不可被修改,意味着如果修改字符串就会产生一个新的字符串
创建字符串
var greeting = "Hello World!"
//或者
var greeting:String = "Hello World!"
String对象是不可变的,如果需要创建一个可变字符串使用StringBuilder类
var buf = new StringBuilder
//char类型使用单引号
buf += 'a'
//拼接字符串这里 使用双加号++=
buf ++= "bc"
字符串长度
使用length()获取字符串长度
var str = "www.baidu.com"
println("长度为"+str.length())
字符串连接
String类中使用concat()来连接两个字符串
同样也可以使用加号(+)来连接
//定义
string1.concat(string2)
def stringConcat(){
var str1 = "hello"
var str2 = "scala"
println(str1.concat(str2))
println(str1 + str2)
}
数组
数组用来存储固定大小的同类型元素
数组的第一个元素索引为0
数组声明
var arr:Array[String] = new Array[String](3)
//或者
var arr = new Array[String](3)
//或者
var arr = Array("Baidu","Tenxun","Alibaba")
数组处理
import Array._
object Test{
def main(args:Array[String]){
var myList = Array(1,2,3,4,5)
//输出数组所有元素
for(x <- myList){
println(x)
}
//计算数组所有元素的总和
var total = 0
for(i <- 0 to (myList.length - 1)){
total += myList[i]
}
println("数组总和为"+total)
//查找数组中最大元素
var max = myList[0]
for(i <- 0 to (myList.length - 1)){
if(myList[i] > max){
max = myList[i]
}
}
println("最大值为"+max)
}
}
多维数组
矩阵和表格是我们常见的二维数组
//二维数组定义
var arr = Array.ofDim[Int](3,3)
//二维数组处理
import Array._
object Test{
def main(args:Array[String]){
var arr = Array.ofDim[Int](3,3,)
//创建矩阵
for(i <- 0 to 2){
for(j <- 0 to 2){
arr(i)(j) = j
}
}
//打印二维矩阵
for(i <- 0 to 2){
for(j <- 0 to 2){
println(" "+arr(i)(j))
}
println()
}
}
}
合并数组
使用concat()方法来合并两个数组
import Array._
object Test{
def main(args:Array[String]){
var arr1 = Array(1,2,3,4)
var arr2 = Array(5,6,7,8)
var arr3 = concat(arr1,arr2)
//输出所有数组元素
for(i <- arr3.length){
println(i)
}
}
}
区间数组
使用range()方法生成范围内的数组,range()方法最后一个参数为步长,默认步长为1
object Test{
def main(args:Array[String]){
var arr1 = range(10,20,2)
var arr2 = range(10,20)
//输出所有元素
for(i <- arr1){
println(" "+ i )
}
println()
for(i <- arr2){
println(" "+ i )
}
}
}
数组常用方法
scala使用处理数组的方法前,需要import Array._ 引入包
集合(Collection)
可变集合:可以修改、添加、移除集合中的元素
不可变集合:集合不会改变,任然可以模拟添加、移除或更新操作,只是返回一个新的集合,原集合不会发生改变
List列表
列表时不可变的,值一旦定义就不能改变
列表的元素类型T可以写成List[T]
//字符串列表
val strList:List[String] = List("scala","spark")
//整型列表
val numList:List[Int] = List(1,2,3)
//空列表
val emptyList:List[Nothing] = List()
//二维列表
val arrList:List[List[Int]]=List(
List(1,0,0)
List(0,1,0)
List(0,0,1)
)
构造列表的两个基本单位:Nil和 ::
Nil也可以表示为空列表
//字符串列表
val strList = "scala"::("spark"::Nil )
//整型列表
val numList = 1::(2::(3::Nil))
//空列表
val emptyList = Nil
//二维列表
val arrList = (1::(0::(0::Nil)))::
(0::(1::(0::Nil)))::
(0::(0::(1::Nil)))::Nil
基本操作
(1)head:返回列表第一个元素
(2)tail:返回一个列表,包含除了第一个元素之外的其他元素
(3)isEmpty:在列表为空时返回true
object Test{
def main(args:Array[String]){
val strList = "scala"::("spark"::Nil )
val numList = Nil
println("第一个单词:"+ strList.head)
println("其他单词为:"+ strList.tail)
println("整型列表是否为空"+numList.isEmpty)
}
}
连接列表
可以使用三冒号(:::)或:::()方法或concat()方法来连接两个或多个列表
object Test {
def main(args: Array[String]) {
val site1 = "Runoob" :: ("Google" :: ("Baidu" :: Nil))
val site2 = "Facebook" :: ("Taobao" :: Nil)
// 使用 ::: 运算符
var fruit = site1 ::: site2
println( "site1 ::: site2 : " + fruit )
// 使用 List.:::() 方法
fruit = site1.:::(site2)
println( "site1.:::(site2) : " + fruit )
// 使用 concat 方法
fruit = List.concat(site1, site2)
println( "List.concat(site1, site2) : " + fruit )
}
}
指定创建重复元素
使用fill()方法可以指定列表中元素的重复次数
object Test {
def main(args: Array[String]) {
val site = List.fill(3)("Runoob") // 重复 Runoob 3次
println( "site : " + site )
//site : List(Runoob, Runoob, Runoob)
val num = List.fill(5)(2) // 重复元素 2, 10 次
println( "num : " + num )
//num : List(2, 2, 2, 2, 2)
}
}
指定函数创建列表
使用tabulate()方法可以通过指定函数来创建列表
参数:第一个表示元素数量,可以是二维的
第二个表示指定的函数,通过函数计算结果并返回值插入到列表中,起始值为0
object Test{
def mian(args:Array[String]){
//通过指定函数创建5个元素的列表
val oneList = List.tabulate(6)(n=>n*n)
println("一维列表"+oneList)
//创建二维列表
//(_*_):是(x,y => x*y)的简写模式
val twoList = List.tabulate(4,5)(_*_)
println("二维列表"+twoList)
}
}
列表反转
使用reverse()方法将列表的顺序反转
object Test {
def main(args: Array[String]) {
val site = "Runoob" :: ("Google" :: ("Baidu" :: Nil))
println( "site 反转前 : " + site )
println( "site 反转后 : " + site.reverse )
}
}
Set集合
没有重复的对象集合,所有元素都是唯一的
默认下使用的是不可变集合(scala.collection.immutable.Set)
若要可变集合,引入scala.collection.mutable.Set包
基本操作
(1)head:返回列表第一个元素
(2)tail:返回一个列表,包含除了第一个元素之外的其他元素
(3)isEmpty:在列表为空时返回true
object Test{
def main(args:Array[String]){
val strSet = Set("scala","spark")
val numSet:Set[Int] = Set()
println("第一个单词:"+ strSet.head)
println("其他单词为:"+ strSet.tail)
println("整型列表是否为空"+numSet.isEmpty)
}
}
连接集合
使用++运算符或++()方法连接两个Set集合,会移除重复元素
object Test {
def main(args: Array[String]) {
val site1 = Set("Runoob", "Google", "Baidu")
val site2 = Set("Faceboook", "Taobao")
// ++ 作为运算符使用
var site = site1 ++ site2
println( "site1 ++ site2 : " + site )
// ++ 作为方法使用
site = site1.++(site2)
println( "site1.++(site2) : " + site )
}
}
查找最大与最小元素
使用min()查找最小元素,使用max()查找最大元素
object Test {
def main(args: Array[String]) {
val num = Set(5,6,9,20,30,45)
// 查找集合中最大与最小元素
println( "Set(5,6,9,20,30,45) 集合中的最小元素是 : " + num.min )
println( "Set(5,6,9,20,30,45) 集合中的最大元素是 : " + num.max )
}
}
交集
使用&()或者intersect()方法查看两个集合交集元素
object Test {
def main(args: Array[String]) {
val num1 = Set(5,6,9,20,30,45)
val num2 = Set(50,60,9,20,35,55)
// 交集
println( "num1.&(num2) : " + num1.&(num2) )
println( "num1.intersect(num2) : " + num1.intersect(num2) )
}
}
Map映射
是一种可迭代的键值对(key-value)结构
键是唯一的,Map也叫哈希表(Hash table)
// 空哈希表,键为字符串,值为整型
var A:Map[Char,Int] = Map()
// Map 键值对演示
val colors = Map("red" -> "#FF0000", "azure" -> "#F0FFFF")
基本操作
(1)keys:返回map中所有的键(key)
(2)values:返回map所有的值(value)
(3)isEmpty:在map为空时返回true
object Test {
def main(args: Array[String]) {
val colors = Map("red" -> "#FF0000","azure" -> "#F0FFFF", "peru" -> "#CD853F")
val nums: Map[Int, Int] = Map()
println( "colors 中的键为 : " + colors.keys )
println( "colors 中的值为 : " + colors.values )
println( "检测 colors 是否为空 : " + colors.isEmpty )
println( "检测 nums 是否为空 : " + nums.isEmpty )
}
}
合并map
使用++运算符或者++()方法连接两个map,会删除重复key
相同的key对应的value会被右边的Map中的值替代
object Test {
def main(args: Array[String]) {
val colors1 = Map("red" -> "#FF0000", "azure" -> "#F0FFFF", "peru" -> "#CD853F")
val colors2 = Map("blue" -> "#0033FF", "yellow" -> "#FFFF00","red" -> "#FF0000")
// ++ 作为运算符
var colors = colors1 ++ colors2
println( "colors1 ++ colors2 : " + colors )
// ++ 作为方法
colors = colors1.++(colors2)
println( "colors1.++(colors2) : " + colors )
}
}
获取K-V
通过foreach获取map的keys和values
object Test{
def main(args:Array[String]){
val strMap = Map("scala"->"sc","spark->sp")
strMap.keys.foreach{i => println("key="+i) println("value="+strMap(i))}
}
}
查看key是否存在
通过contain()方法查看map中是否存在指定key
object Test {
def main(args: Array[String]) {
val strMap = Map("scala"->"sc","spark->sp")
if( strMap.contains( "scala" )){
println("scala 键存在,对应的值为 :" + strMap("scala"))
}else{
println("scala 键不存在")
}
}
}
Tuple元组
与列表一样,元组也是不可变的,可以包含不同类型的元素,元组的值是通过将单个值包含在圆括号中构成
val tu = (1,3.14,"scala")
//或者
val tu = new Tuple(1,3.14,"scala")
访问元组元素
可以使用t._1访问第一个元素,使用t._2访问第二个元素
object Test{
def main(args:Array[String]){
val tu = (1,2,3,4)
val sum = t._1+t._2+t._3+t._4
println("元素和为:"+sum)
}
}
迭代元组
使用Tuple.productiterator()方法来迭代输出元组所有元素
object Test {
def main(args: Array[String]) {
val tu = (4,3,2,1)
tu.productIterator.foreach{ i =>println("Value = " + i )}
}
}
元组转字符串
使用Tuple.toString()方法将元组所有元素转换成字符串
object Test {
def main(args: Array[String]) {
val t = new Tuple3(1, "hello", Console)
println("连接后的字符串为: " + t.toString() )
}
}
元素交换
使用Tuple.swap()方法交换元组元素
object Test {
def main(args: Array[String]) {
val t = new Tuple2("www.google.com", "www.runoob.com")
println("交换后的元组: " + t.swap )
}
}
Option选项
用来表示一个值是可选的(有值或无值)
Option[T]是一个类型为T的可选值的类型。如果值存在,Option[T]就是一个Some[T];如果不存在,Option[T]就是对象None
val myMap: Map[String, String] = Map("key1" -> "value")
val value1: Option[String] = myMap.get("key1")
val value2: Option[String] = myMap.get("key2")
println(value1) // Some("value1")
println(value2) // None
迭代器(Iterator)
用于访问集合的方法
基本操作
(1)next():返回迭代器的下一个元素,并且更新迭代器的状态
(2)hasNext():用于检测集合中是否还有元素
让迭代器it逐个返回所有元素最佳单的方法是使用while循环
object Test {
def main(args: Array[String]) {
val it = Iterator("Baidu", "Google", "Runoob", "Taobao")
while (it.hasNext){
println(it.next())
}
}
}
类和对象
类是对象的抽象,而对象是类的具体实例
类是抽象的不占用内存,而对象是具体的占用存储空间
继承
(1)重写一个非抽象方法必须使用override修饰符
(2)只有主构造函数才可以往基类的构造函数里写参数
class Point(xc: Int, yc: Int) {
var x: Int = xc
var y: Int = yc
def move(dx: Int, dy: Int) {
x = x + dx
y = y + dy
println ("x 的坐标点: " + x);
println ("y 的坐标点: " + y);
}
}
//override val xc为重写了父类的字段
//使用extends关键字表示继承
class Location(override val xc: Int, override val yc: Int,val zc :Int) extends Point(xc, yc){
var z: Int = zc
def move(dx: Int, dy: Int, dz: Int) {
x = x + dx
y = y + dy
z = z + dz
println ("x 的坐标点 : " + x);
println ("y 的坐标点 : " + y);
println ("z 的坐标点 : " + z);
}
}
Scala只允许继承一个父类
单例对象
在Scala中是没有static的
使用object关键字实现单例模式
单例模式中,除了定义的类之外,还需定义一个同名的object对象,object对象不能带参数
当单例对象与某个类名称相同时,称为这个类的伴生对象(companion object),必须在同一个源文件里定义类和他的伴生对象。类被称为这个单例对象的伴生类(companion class)。类和他的伴生对象可以互相访问其私有成员
// 私有构造方法
class Marker private(val color:String) {
println("创建" + this)
override def toString(): String = "颜色标记:"+ color
}
// 伴生对象,与类名字相同,可以访问类的私有属性和方法
object Marker{
private val markers: Map[String, Marker] = Map(
"red" -> new Marker("red"),
"blue" -> new Marker("blue"),
"green" -> new Marker("green")
)
def apply(color:String) = {
if(markers.contains(color)) markers(color) else null
}
def getMarker(color:String) = {
if(markers.contains(color)) markers(color) else null
}
def main(args: Array[String]) {
println(Marker("red"))
// 单例函数调用,省略了.(点)符号
println(Marker getMarker "blue")
}
}
特征Trait
相当于Java的接口,实际上比接口功能强大
特征还可以定义属性和方法的实现
特征(Trait)定义方式与类相似,使用trait关键字
要使用trait中定义的方法,需要先继承(可继承多个特征)
//triat定义特征
//特征中,可以选择性定义方法实现(类比Java抽象类)
trait Equal {
def isEqual(x: Any): Boolean
def isNotEqual(x: Any): Boolean = !isEqual(x)
}
//使用extends继承特征,用于使用特征中定义的方法
class Point(xc: Int, yc: Int) extends Equal {
var x: Int = xc
var y: Int = yc
def isEqual(obj: Any) =
obj.isInstanceOf[Point] &&
obj.asInstanceOf[Point].x == x
}
object Test {
def main(args: Array[String]) {
val p1 = new Point(2, 3)
val p2 = new Point(2, 4)
val p3 = new Point(3, 3)
println(p1.isNotEqual(p2))
println(p1.isNotEqual(p3))
println(p1.isNotEqual(2))
}
}
特征构造顺序
特征也可以有构造器,由字段的初始化和其他特征体的语句构成
构造器执行顺序:
(1)调用超类的构造器
(2)特征构造器在超类构造器之后、类构造器之前执行
(3)特征由左到右被构造
(4)每个特征中,父特征先被构造
(5)如果多个特征中共有一个父特征,该父特征只会被构造一次
(6)所有特征被构造完毕,子类被构造
模式匹配
模式匹配包含了一系列备选项(使用关键字case修饰)
格式:选择器match{备选项}
只要发现一个匹配的case,剩下的case就不会继续匹配
object Test{
def main(args:Array[String]){
println(matchTest(3))//other
}
def matchTest(x:Int):String = x match{
case 1 => "one"
case 2 => "two"
case 3 => "three"
case _ => "other"
}
}
样例类
使用case关键字修饰的类,经过优化用于模式匹配
object Test {
def main(args: Array[String]) {
val alice = new Person("Alice", 25)
val bob = new Person("Bob", 32)
val charlie = new Person("Charlie", 32)
for (person <- List(alice, bob, charlie)) {
person match {
case Person("Alice", 25) => println("Hi Alice!")
case Person("Bob", 32) => println("Hi Bob!")
case Person(name, age) =>
println("Age: " + age + " year, name: " + name + "?")
}
}
}
// 样例类
case class Person(name: String, age: Int)
}
声明样例类时发生下列过程
(1)构造器的每个参数变成了val
(2)在伴生对象中提供了apply方法,所以可以不使用new关键字就可以构建对象
(3)提供unapply方法使模式匹配可以工作
(4)生成tpString、eqauls、hashCode和copy方法
正则表达式
通过导入scala.util.matching.Regex包支持
import scala.util.matching.Regex
object Test {
def main(args: Array[String]) {
//使用String类的r()方法构建Regex对象
//可以直接new Regex("str")构建Regex对象
val pattern = "Scala".r
val str = "Scala is Scalable and cool"
//使用findFirstIn找到首个匹配项
println(pattern findFirstIn str)
//输出Some(Scala)
}
}
将匹配文本替换:
使用replaceFirstIn()方法替换第一个匹配项,使用replaceAllIn()替换所有匹配项
object Test {
def main(args: Array[String]) {
//通过new Regex()构建对象
val pattern = new Regex("(S|s)cala")
val str = "Scala is scalable and cool"
println(pattern replaceFirstIn(str, "Java"))
}
}
异常处理
抛出异常:
throw new IllegalArgumentException
捕获异常:
使用模式匹配思想来在catch中捕获异常(在catch中是一系列case选项)
object Test {
def main(args: Array[String]) {
try {
val f = new FileReader("input.txt")
} catch {
case ex: FileNotFoundException =>{
println("Missing file exception")
}
case ex: IOException => {
println("IO Exception")
}
}
}
}
提取器(Extracor)
提取器是从传递给它的对象中提取出构造该对象的参数
Scala提取器是一个带有unapply()方法的对象,unapplyu接受一个对象,然后从对象中提取值,提取的值通常是用来构造该对象的值
object Test {
def main(args: Array[String]) {
//Apply 方法 : Zara@gmail.com
println ("Apply 方法 : " + apply("Zara", "gmail.com"));
//Unapply 方法 : Some((Zara,gmail.com))
println ("Unapply 方法 : " + unapply("Zara@gmail.com"));
//Unapply 方法 : None
println ("Unapply 方法 : " + unapply("Zara Ali"));
}
// 注入方法 (可选)
def apply(user: String, domain: String) = {
user +"@"+ domain
}
// 提取方法(必选)
def unapply(str: String): Option[(String, String)] = {
val parts = str split "@"
if (parts.length == 2){
Some(parts(0), parts(1))
}else{
None
}
}
}
提取器使用模式匹配:
object Test {
def main(args: Array[String]) {
//通过apply()方法实例化对象
val x = Test(5)
println(x)
x match
{
case Test(num) => println(x + " 是 " + num + " 的两倍!")
//unapply 被调用
case _ => println("无法计算")
}
}
def apply(x: Int) = x*2
def unapply(z: Int): Option[Int] = if (z%2==0) Some(z/2) else None
}
通过apply()方法我们无需使用new关键字来构建对象
文件IO
scala进行文件读写操作,直接用的是java中的IO类(java.io.File)
import java.io._
object Test {
def main(args: Array[String]) {
val writer = new PrintWriter(new File("test.txt" ))
writer.write("hello scala")
writer.close()
}
}
读取用户输入
使用scala.io.StdIn类
import scala.io._
object Test {
def main(args: Array[String]) {
print("请输入 : " )
val line = StdIn.readLine()
println("谢谢,你输入的是: " + line)
}
}
读取文件内容
通过Scala的Source类及伴生对象来读取文件
import scala.io.Source
object Test{
def main(args:Array[String]){
println("文件内容为:")
Source.fromFile("test.txt").foreach{
print
}
}
}