Scala notes finishing (1): basic knowledge of scala

[TOC]


Introduction to Scala

Scala is a multi-paradigm programming language designed to integrate various features of object-oriented programming and functional programming.

Scala runs on the Java Virtual Machine and is compatible with existing Java programs.

Scala source code is compiled into Java bytecode, so it can run on the JVM and call existing Java class libraries.

The functional programming paradigm is more suitable for Map/Reduce and big data models. It abandons the computing model of data and state, and focuses on the function itself, rather than the processing of data and state in the process of execution. The functional paradigm is logically clear and simple, and is very suitable for batch processing jobs based on immutable data. These jobs basically transform data through map and reduce operations, generate new data copies, and then process them.

Like Spark, Flink, etc., are developed in Scala, so it is necessary to learn big data and master scala.

Official website:http://scala-lang.org/

Scala installation verification

1、安装JDK

2、JAVA_HOME, PATH

3、Maven

4、SCALA SDK

下载地址:http://scala-lang.org/download/all.html

    这里选择的版本为Scala 2.10.5,分为windows和linux版本

5、配置SCALA_HOME

    在windows环境变量中添加SCALA_HOME

6、验证
scala -version
Scala code runner version 2.10.5 -- Copyright 2002-2013, LAMP/EPFL

Getting Started

object HelloWorld {
    def main(args:Array[String]):Unit = {
        println("Hello World!")
    }
}

Save as HelloWorld.scala, and then perform the following two steps:

scalac HelloWorld.scala
scala HelloWorld

Scala basics and syntax

Language Features

1.可拓展
    面向对象
    函数式编程

2.兼容JAVA
    类库调用
    互操作

3.语法简洁
    代码行短
    类型推断
    抽象控制

4.静态类型化
    可检验
    安全重构

5.支持并发控制
    强计算能力
    自定义其他控制结构

The relationship between Scala and Java

  • 1. They are all based on the JVM virtual machine.

    The files compiled by Scala are also .classes, which must be converted into bytecodes and then run on the JVM virtual machine.

  • 2. Scala and Java call each other

    You can directly call Java code in Scala, and you can also directly call Scala code in Java

  • 3、Java8 VS Scala

    1) Before Java8 (lambda) came out, Java was only an object-oriented language, but after Java8 came out, Java was a mixed language of object-oriented and function-oriented.

    2) First of all, we have to precisely locate Scala. To a certain extent, Scala is not a purely function-oriented programming language. Some people think that Scala is a static object-oriented language with closures), more precisely , Scala is a mix of function-oriented and object-oriented.

    3) The original intention of Scala's design was to be FP-oriented, while Java started out as object-oriented OO. Now both are mixed languages ​​of OO and FP. Can you think so: Scala = FP + OO, and Java = OO + FP?

    Since the two paradigms of object-oriented OO and function-oriented FP are similar to the abscissa and ordinate, they are thinking in different coordinate directions, similar to the mismatched impedance relationship between the database and the object. Will have the effect of 1+1>2.

    Object-oriented is the closest to the human way of thinking, and function-oriented is the closest to the computer way of thinking. If you want computers to serve people's business modeling, then focus on OO; if you want computers to automatically model from big data through algorithms, then focus on FP. Therefore, Java may still occupy the main market in enterprise engineering software, while Scala will seize the Java market in fields such as scientific computing and big data analysis. For example, Scala's Spark has a tendency to replace Java's Hadoop.

Scala interpreter and IDEA

1. The Scala interpreter reads an expression, evaluates it, prints it, and then moves on to the next expression. This process is called read-evaluate-print-loop, ie: REPL.

Technically, a scala program is not an interpreter. What actually happens is that what you type is quickly compiled into bytecode, which is then executed by the Java virtual machine. Because of this, most scala programmers prefer to call it "REPL"

2、scala

scala>"Hello"
res1: String = Hello
scala> 1+2
res5: Int = 3
scala>"Hello".filter(line=>(line!='l'))
res2: String = Heo

You should have noticed that after each statement we type into the interpreter, it prints a line of information like res0:
java.lang.String
= Hello. The first part of the output is the variable name that the REPL gave the expression. In these examples, the REPL defines a new variable (res0 to res3) for each expression. The second part of the output (the part after the :) is the static type of the expression. The type of the first example is java.lang.String, and the type of the last example is scala.util.matching.Regex. The last part of the output is a stringified display of the result of evaluating the expression. Generally, it is the output obtained by calling the toString method on the result. The JVM defines the toString method for all classes.

Scala notes finishing (1): basic knowledge of scala

var and val define variables

1. There is no static class in Scala, but he has a similar companion object

2. Field:

Field/variable definition is defined in Scala using var/val variable/invariant name: type, for example:

var index1 : Int = 1  
val index2 : Int = 1 

The difference between var and val is that var is a variable, and its value can be changed in the future. The value of val can only be assigned at the time of declaration, but val is not a constant, it can only be said to be an invariant or a read-only variable.

3. Everyone will definitely feel that this var/val name: the type declaration method is too cumbersome, there is another way

So when you declare a field, you can use the compiler to automatically infer the type, that is, without writing : 类型, for example:

var index1 = 1  (类型推断)
val index2 = 1  

This example demonstrates a capability called type inference, which allows Scala to automatically understand types that you omit. Here, you initialize index1 with an int literal, so scala infers that index2 is of type Int. For cases where types can be automatically inferred by the Scala interpreter (or compiler), there is no need to write type annotations.

4. a. Method (b)

The method here is a method with 2 parameters (one explicit and one implicit)

1.to(10), 1 to 10, 1 until 10

scala> 1.to(10)
res19: scala.collection.immutable.Range.Inclusive = Range(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)

scala> 1 to 10
res20: scala.collection.immutable.Range.Inclusive = Range(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)

scala> 1 until 10
res21: scala.collection.immutable.Range = Range(1, 2, 3, 4, 5, 6, 7, 8, 9)

5. In fact, according to the idea of ​​functional programming, the var variable is a bad existence. In Scala, it is recommended that you use the val invariant as much as possible. The main reason is that

  • 1) The immutability of val helps to clear things up, but it will pay a part of the performance cost.
  • 2) Another point is that if you use var, you may worry about the value being changed by mistake.
  • 3) The second advantage of using val instead of var is that he can better support the equivalent inference (a=b, b=c —> a=c)

Data Types and Operators

​ Scala has the same data types as Java, and the memory layout and precision are exactly the same as Java's data types.

The following table shows the data types supported by scala:

Scala notes finishing (1): basic knowledge of scala

The data types listed in the above table are all objects, which means that scala does not have the native type in java. That is to say, scala has no concept of basic data types and wrapper types.

In Scala, you can omit empty parentheses around method calls. The exception is to add parentheses if the method has side effects, such as println(), but if the method has no side effects, the parentheses can be removed, such as toLowerCase called on String:

scala> "Hello".toLowerCase
res22: String = hello

scala> "Hello".toLowerCase()
res23: String = hello

computation

In Scala, you can omit empty parentheses around method calls. The exception is to add parentheses if the method has side effects, such as println(), but if the method has no side effects, the parentheses can be removed, such as toLowerCase called on String:

You can call mathematical methods on any number type with the infix operators, plus (+), minus (-), multiplication (*), division (/) and remainder (%), basics in scala The operation is consistent with java

scala> 1.2 + 2.3 
res6: Double = 3.5 
scala> 3 - 1 
res7: Int = 2 
scala> 'b' - 'a' 
res8: Int = 1 
scala> 2L * 3L 
res9: Long = 6 
scala> 11 / 4 
res10: Int = 2 
scala> 11 % 4 
res11: Int = 3 
scala> 11.0f / 4.0f 
res12: Float = 2.75 
scala> 11.0 % 4.0 
res13: Double = 3.0

Relationships and Logical Operations

You can compare numeric types using the relational methods: greater than (>), less than (<), greater than or equal to (>=), and less than or equal to (<=), like the equals operator, producing a Boolean result. In addition, you can use the unary operator ! (unary_! method) to change the Boolean value

scala> 1 > 2 
res16: Boolean = false 
scala> 1 < 2 
res17: Boolean = true 
scala> 1.0 <= 1.0 
res18: Boolean = true 
scala> 3.5f >= 3.6f 
res19: Boolean = false 
scala> 'a' >= 'A' 
res20: Boolean = true 
scala> val thisIsBoring = !true 
thisIsBoring: Boolean = false 
scala> !thisIsBoring
res21: Boolean = true

object equality

scala> ("he" + "llo") == "hello" 
res33: Boolean = true 
=== 比较2个不同的对象
scala> 1 == 1.0 
res34: Boolean = true 

It compares values, not address values ​​in Java concepts. In addition, the second example, 1 == 1.0, will be true because 1 will be promoted to 1.0

Scala control structures

If expression has value

1. Scala's if/else syntax is the same as Java or C++, but in Scala if/else expressions have a value, this value is the value of the expression following if or else

val x = 3
if(x > 0) 1 else -1

The value of the above expression is 1 or -1 depending on the value of x, and you can also copy the value of the if/else expression to a variable

val s = if(x>0) 1 else -1 // 这与如下语句的效果是一样的
if(x >0) s = 1 else s =-1

However, the first way is better because it can be used to initialize a val, while in the second way, s must be a var

2、val result = if(personAge &gt; 18) "Adult" else 0

One of the branches is java.lang.string and the other is of type Int, so their public superclass is Any

3. If else is lost

if(x>0) 1

Then it is possible that the if statement has no output value, but in Scala, every expression has a value. The solution to this problem is to introduce a Unit class, written as (), the if statement without the else statement is equivalent toif(x&gt;0) 1else ()

statement terminated

1. In Java and C++, each statement is terminated by a semicolon. But in Scala—similar to JavaScript and other languages—the semicolon is not required at the end of the line. Also, semicolons are not required in }, else, and similar positions.

However, if you want to write multiple statements on a single line, you need to separate them with semicolons

If(n>0){r = r *n ; n-=1}

We need to separate r = r *n and n -=1 with a semicolon, because of the }, there is no need to write a semicolon after the second statement.

2. Branch display

If(n>0){
    r = r *n
    n-=1
}

Fast expressions and assignments

  • In Java or C++, a quick statement is a sequence of statements enclosed in }. Whenever you need to branch in logic or like to perform multiple actions, you can use quick statements.
  • In Scala, {} contains some column expressions whose result is also an expression. The value of the last expression in the block is the fast value .
scala> val n = 9
n: Int = 9

scala> var f = 0
f: Int = 0

scala> var m = 5
m: Int = 5

scala> val d = if(n < 18){f = f + n ; m = m + n ; f + m}
d: AnyVal = 23

input and output

If we want to print a value, we use the print or println function. The latter appends a newline after printing the content. for example,

print("Answer:")
println(42)

The same output as the code below:

println("Answer:" + 42)

Also, there is a printf function with a C-style format string: system.in

printf("Hello,%s! You are %d years old.\n", "Fred", 42)

You can read a line of input from the console with the readLine function. If you want to read numbers, Boolean or characters, you can use readInt, readDouble, readByte, readShort, readLong, readFloat, readBoolean or readChar. Unlike the other methods, readLine takes one parameter as a prompt string:

scala> val name = readLine("Please input your name:")
Please input your name:name: String = xpleaf

A simple input-output case is as follows:

val name = readLine("What's Your name: ")
    print("Your age: ")
    val age = readInt()
    if(age > 18) {
        printf("Hello, %s! Next year, your will be %d.\n", name, age + 1)
    }else{
        printf("Hello, %s! You are still a children your will be %d.\n", name, age + 1 +" Come up!!!")
    }
}

while loop

Scala has the same while and do loops as Java and C++. E.g:

object _04LoopDemo {
    def main(args: Array[String]):Unit = {
        var sum = 0
        var i = 1
        while(i < 11) {
            sum += i
            i += 1
        }
    }
}

do while loop

Scala also has a do-while loop, which is similar to a while loop, except that the condition is checked after the loop body is executed. E.g:

object _04LoopDemo {
    def main(args: Array[String]):Unit = {
        var sum = 0
        var i = 1
        do {
            sum += i
            i += 1
        } while(i <= 10)
        println("1+...+10=" + sum)
    }
}

Login user name and password game: three chances, enter the user name and password from the console, if the login is successful, it will return the login success, if it fails, it will return an error message! as follows:

object _05LoopTest {
    def main(args: Array[String]):Unit = {
        val dbUser = "zhangyl"
        val dbPassword = "uplooking"
        var count = 3

        while(count > 0) {
            val name = readLine("亲,请输入用户名:")
            val pwd = readLine("请输入密码:")
            if(name == dbUser && pwd == dbPassword) {
                println("登陆成功,正在为您跳转到主页呐," + name + "^_^")
                // count = 0
                return
            } else {
                count -= 1
                println("连用户名和密码都记不住,你一天到底在弄啥嘞!您还有<" + count + ">次机会")
            }
        }

    }
}

for loop

Scala doesn't have a for(初始化变量;检查变量是否满足某条件;更新变量)direct counterpart to loops. If you need such a loop, you have two options: one is to use a while loop, and the other is to use a for statement like this:

for (i <- 表达式)

Let the variable iiterate over &lt; -all values ​​of the expression on the right. How this traversal is performed depends on the type of expression. For Scala collections such as Range, this loop will cause i to take each value in the range in turn.

When iterating over strings or arrays, you usually need to use the range from 0 to n-1. This time you can use the until method instead of the to method. The util method returns an interval that does not contain an upper bound.

val s = "Hello"
var sum = 0
for (i <-  0 until s.length) {  // i的最后一个取值是s.length - 1
    sum += s(i) // 注意此时为对应的ASCII值相加
} 

In this case, we don't actually need to use subscripts. You can iterate directly over the corresponding character sequence:

var sum = 0
for (ch <- "Hello") sum += ch

loop out of loop

Note: Scala does not provide a break or continue statement to exit a loop. So what should we do if we need to break? There are the following options:

    1. Use Boolean control variables.
    1. Use nested functions - you can return from functions.
    1. Use the break method in the Breaks object:
object _06LoopBreakTest {
    def main(args: Array[String]):Unit = {
        import scala.util.control.Breaks._
        var n = 15
        breakable {
            for(c <- "Spark Scala Storm") {
                if(n == 10) {
                    println()
                    break
                } else {
                    print(c)
                }
                n -= 1
            }
        }
    }
}

Advanced features of for loop

1. In addition to the basic form of the for loop, Scala also provides other rich advanced features. For example, multiple groups of structures can be included in the for loop parentheses at the same time 变量 &lt;- 表达式, and the groups are separated by semicolons

for (i <- 1 to 3;j <- 1 to 3) print ((10 * i +j) + " ")

This structure of for loop is similar to the nested loop structure in Java.

For example, to implement a nine-nine multiplication table, when using the basic for loop form, the code is as follows:

object _07LoopForTest {
    def main(args: Array[String]):Unit = {
        for(i <- 1 to 9) {
            for(j <- 1 to i){
                var ret = i * j
                print(s"$i*$j=$ret\t")
            }
            // println()
            System.out.println()
        }
    }
}

And when using the advanced for loop, as follows:

object _07LoopForTest {
    def main(args: Array[String]):Unit = {
        // for(i <- 1 to 9; j <- 1 to 9 if j <= i) {
        for(i <- 1 to 9; j <- 1 to i) {
            var ret = i * j
            print(s"$i*$j=$ret\t")
            if(i == j) {
                println
            }
        }
    }
}

2, if loop guard

You can add conditions to nested loops through if expressions:

for (i <- 1 to 3; j <- 1 to 3 if i != j) print ((10 * i + j) + " ")

Whether parentheses are added to the if expression, the result remains unchanged:

for (i <- 1 to 3; j <- 1 to 3  if (i != j)) print ((10 * i + j) + " ")

Note: Note that there is no semicolon before the if.

3. For derivation

Yield in Scala is not like yield in Ruby, yield in Ruby is like a placeholder. The main function of yield in Scala is to remember the relevant values ​​in each iteration and store them into an array one by one. The usage is as follows:

for {子句} yield {变量或表达式}

1) If the body of the for loop starts with yield, the loop constructs a set, and each iteration generates a value in the set:

scala> for(i <- 1 to 10) yield println(i % 3)
1
2
0
1
2
0
1
2
0
1
res47: scala.collection.immutable.IndexedSeq[Unit] = Vector((), (), (), (), (), (), (), (), (), ())

scala> val ret1 = for(i <- 1 to 10) yield(i)
ret1: scala.collection.immutable.IndexedSeq[Int] = Vector(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)

scala> for(i <- ret1) println(i)
1
2
3
4
5
6
7
8
9
10

2) The yield in the for loop will write down the current element, save it in the collection, and return to the collection after the loop ends

The for loop in Scala has a return value. If the looped is Map, the returned is Map, the looped is List, the returned is List, and so on.

A short summary of the yield keyword:

1.针对每一次for循环的迭代, yield会产生一个值,被循环记录下来(内部实现上,像是一个缓冲区)
2.当循环结束后, 会返回所有yield的值组成的集合
3.返回集合的类型与被遍历的集合类型是一致的

exception handling

Scala's exception handling is similar to other languages ​​such as Java. A method can terminate the execution of related code by throwing an exception method without returning a value. The calling function can catch the exception and handle it accordingly or exit directly. In this case, the exception will be passed to the caller of the calling function, which will be passed up in turn until there is a way to handle the exception.

object _01ExceptionDemo {
    def main(args:Array[String]):Unit = {
        import scala.io.Source
        import java.io.FileNotFoundException
        try {
            val line = Source.fromFile("./wordcount.txt").mkString
            val ret = 1 / 0
            println(line)
        } catch {
            case fNFE:FileNotFoundException => {
                println("FileNotFoundException:文件找不到了,传的路径有误。。。")
            }
            case e:Exception => {
                println("Exception: " + e.getMessage)
            }
            case _ => println("default处理方式")
        } finally {
            println("this is 必须要执行的语句")
        }
    }
}

Scala functions

Function definition and call (class member function)

Scala supports functions in addition to methods. Methods operate on objects, functions do not. To define a function, you need to give the function's name, parameters, and function body, like this:

Scala notes finishing (1): basic knowledge of scala

The following are issues to be aware of:

  • 1. You must give the types of all parameters. However, as long as the function is not recursive, you don't need to specify the return type. The Scala compiler can infer the return type from the type of the expression to the right of the = sign.
  • 2. "=" is not just used to separate function signatures and function bodies. Another function of "=" is to tell the compiler whether to perform type inference on the return value of the function! If the = is omitted, the function is considered to have no return value!
def myFirstFunction(name:String, age:Int) : String ={
    println("name=> " + name +"\t age=> " + age)
    "Welcome " + name + " to our world, your age is => " + age
}

We don't need to use return in this example. We can also use return like in Java or C++ to immediately exit from a function, but this is not common in Scala.

Tip: While there's nothing wrong with using return in a named function (other than wasting 7 keystrokes), we'd better get used to the days without return. Soon, you'll be using a lot of anonymous functions that return and don't return a value to the caller. It jumps out into the named function that contains it. We can think of return as a functional version of the break statement, used only when needed.

function with no return value

def myFirstFunctionWithoutFeedBackValues: Unit ={
    println("This is our first function without feedback values")
}

one-line function

def printMsg(name:String) = println("Hello, " + name +", welcome happy day!!!")

The case of the corresponding function above is as follows:

/**
    注意:
    1.scala中如果要给一个函数做返回值,可以不用return语句,
    使用也是可以的,但是scala语言强烈建议大家不要用
    因为scala崇尚的是简约而不简单
    一般也就是将这个return当做break来使用

    2.在scala中在同一条语句中,变量名不能和引用函数名重复

    3.使用递归时,需要指定返回值类型
*/
object _02FunctionDemo {
    def main(args:Array[String]):Unit = {
        // val ret = myFirstFunc("xpleaf", 23)
        // println(ret)
        // show("xpleaf", 23)

        // val ret = singleLineFunc("xpleaf")
        // println(ret)

        val ret = factorial(5)
        println(ret)
    }

    def testFunc(num:Int) = {
        if(num == 1) {
            1
        }
        10
    }

    // 使用递归来求解5的阶乘
    def factorial(num:Int):Int = {
        if(num == 1) {
            1
        } else {
            num * factorial(num - 1)
        }
        // 如果num * factorial(num - 1)不写在else里面,则需要return,否则会有异常,
        // testFunc中则不会这样,所以猜测递归函数才会有此问题
    } 

    // 单行函数
    def singleLineFunc(name:String) = "hello, " + name  // 有"="号,有返回值,自动判断返回值类型
    // def singleLineFunc(name:String) {"hello, " + name}   // 没有“=”号,没有返回值
    // def singleLineFunc(name:String):Unit = "hello, " + name  // 有"="号,但指定返回值为空,相当于没有返回值
    // def singleLineFunc(name:String) = println("hello, " + name)  // 没有返回值,println并不是一个表达式

    // 没有返回值的函数
    def show(name:String, age:Int):Unit = {
        println(s"My name is $name, and I'm $age years old.")
    }

    // 有返回值的函数
    def myFirstFunc(name:String, age:Int):String = {
        println(s"My name is $name, and I'm $age years old.")
        // return "Welcome you " + name + ", make yourself..."
        "Welcome you " + name + ", make yourself..."
    }

}

Default parameters and named parameters

1. We do not explicitly give all parameter values ​​when calling some functions, for these functions we can use default parameters.

def sayDefaultFunc(name: String, address: String = "Beijing", tellphone: String ="139****") ={
    println(name +"address=> " + address +"\t tellphone=> " + tellphone)
}

2. When no specific parameters are specified: give default values

sayDefaultFunc("Garry")

3. If the value you give is not enough relative to the number of parameters, the default parameters will be applied one by one from back to front.

sayDefaultFunc("Garry","Shanhai")

4. Give all parameter values

sayDefaultFunc("Garry","Shanhai","13709872335")

5. Named parameters can make functions more readable. They are also useful for functions that have many default arguments.

sayDefaultFunc(address ="上海", tellphone="12109876543",name="Tom")

6. You can mix unnamed and named parameters, as long as those unnamed parameters come first:

sayDefaultFunc("Tom",tellphone="12109876543",address= "上海")

Variable parameters (1)

The parameters of the functions we introduced earlier are fixed. This article introduces the variable parameter list, named parameters and parameter default value definitions supported by Scala functions.

Repeat parameter

Scala allows to specify that the last parameter can be repeated (variable-length parameter) when defining a function, thereby allowing the function caller to use a variable-length parameter list to call the function. In Scala, "*" is used to indicate that the parameter is a repeating parameter. E.g

Scala:

def echo(args: String*) = {
    for (arg <- args) println(arg)
}

Java:

public staticvoid echo(String ...args){
    for(String str: args){
        System.out.println(str)
    }
}

Variable parameters (two)

1. Inside the function, the type of variable-length parameter is actually an array. For example, the String* type in the above example is actually Array[String].
However, now that you try to pass an array type parameter directly to this parameter, the compiler will report an error:

val arr= Array("Spark","Scala","AKKA")
Error message as bellows:
error: type mismatch;

2. To avoid this situation, you can solve it by adding _* after the variable, this symbol tells the Scala compiler to pass in each element of the array one by one when passing parameters, instead of the array as a whole

val arr= Array("Spark","Scala","AKKA")
echo(arr:_*)

An example is as follows:

object _04FunctionDemo {
    def main(args:Array[String]):Unit = {
        show("Spark", "Strom", "Hadoop")

        var arr = Array("Spark", "Strom", "Hadoop")
        show(arr:_*)
    }

    def show(strs:String*) {
        for(str <- strs) {
            println(str)
        }
    }
}

Process

1. Scala has a special notation for functions that do not return a value. If the function body is enclosed in curly braces without the preceding = sign, then the return type is Unit. Such functions are called procedures. A procedure does not return a value, we call it only for its side effects.

Case:

For example: we need to print some patterns, then we can define a process:

def draw(str:String) {
    println("-------")
    println("|"+"   "+"|")
    println("|"+ str +"|")
    println("|"+"   "+"|")
    println("-------")
}

2. We can also display the return value of the specified function: Unit

Scala Lazy Features

1. When val is declared lazy, its initialization will be deferred until we first evaluate it. E.g,

lazy val lines= scala.io.Source.fromFile("D:/test/scala/wordcount.txt").mkString

2. If the program never accesses lines, the file will not be opened. But intentionally misspelled the filename. No error is reported when the initialization statement is executed. However, once you access words, you will get an error message: file not found.

3. Lazy values ​​are useful for expensive initialization statements. They can also cope with other initialization problems, such as circular dependencies. More importantly, they are the basis for developing lazy data structures. (The bottom layer of spark relies heavily on these lazy)

4. Loading (it will only be loaded when you use it)

println(lines)

An example is as follows:

object _05LazyDemo {
    def main(args:Array[String]):Unit = {
        import scala.io.Source
        import java.io.FileNotFoundException
        try {
            lazy val line = Source.fromFile("./wordcountq.txt").mkString    // wordcountq.txt这个文件并不存在
            // println(line)
        } catch {
            case fNFE:FileNotFoundException => {
                println("FileNotFoundException:文件找不到了,传的路径有误。。。")
            }
            case e:Exception => {
                println("Exception: " + e.getMessage)
            }
        } finally {
            println("this is 必须要执行的语句")
        }
    }
}

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324513974&siteId=291194637