SCALA学习笔记(一)

变量



获取变量的值是一个耗时的工作时,可以考虑使用lazy var.

lazy val forLater = someTimeConsumingOperation()



scala> val first :: rest = List(1, 2, 3)

first: Int = 1

rest: List[Int] = List(2, 3)


函数定义



“=”并不只是用来分割函数签名和函数体的,它的另一个作用是告诉编译器是否对函数的返回值进行类型推断!如果省去=,则认为函数是没有返回值的!

比如:

scala> def myFirstMethod() = { “exciting times ahead” }

myFirstMethod: ()java.lang.String

scala> def myFirstMethod(){ “exciting times ahead” }

myFirstMethod: ()Unit


函数字面量:FUNCTION LITERALS



In Scala you can also pass a function as a parameter to another function, and most of the time in those cases I provide an inline definition of the function. This passing of functions as a parameter is sometimes loosely called closure (passing a function isn’t always necessarily closure; you’ll look into that in chapter 4). Scala provides a shorthand way to create a function in which you write only the function body, called function literals.

简单地说就是: 函数字面量就是省去了函数签名(主要就是函数名和参数声明)只留下函数体的一段代码!注意,这个还不同于匿名函数,匿名函数只是没有函数名,但是参数声明是不会省略的!对于函数字面量来讲,因为省略了参数声明,当函数体内需要使用到参数时,就会使用一个下划线来指代!这也可以说是函数字面量的一个特征了!

例如:

//很显然,花括号中的部分是一个匿名函数
scala> evenNumbers.foldLeft(0) { (a: Int, b:Int) => a + b }  

//花括号中的部分依然是匿名函数,只是省去了参数的类型声明
scala> evenNumbers.foldLeft(0) { (a, b) => a + b } 

//演化到这个版本时,发生了一些实质性的变化:
//参数声明也被省略了,很显然,我们再也不能将其称之为匿名函数了!
//随着参数声明的取消,带来了一个问题:如何在函数体内指代和标示参数呢?
scala> evenNumbers.foldLeft(0) { _ + _ }  

在scala里, 一个下划线代表一个参数!


闭包:Closure



A closure is any function that closes over the environment in which it’s defined. For example, closure will keep track of any variable changes outside the function that are being referred to inside the function.



def breakable(op: => Unit) { … }

What’s this op: => Unit? The special right arrow (=>) lets Scala know that the breakable function expects a function as a parameter. The right side of the => defines the return type of the function—in this case it’s Unit (similar to Java void)—and op is the name of the parameter. Because you haven’t specified anything on the left side of the arrow, it means that the function you’re expecting as a parameter doesn’t take any parameter for itself.

如果我们需要的传入参数是一个代参数且有返回值的函数呢? 这样的函数作参数应该如何描述呢?

def foldLeft(initialValue: Int, operator: (Int, Int) => Int)= { … }

让我们这样来理解吧:既然对于函数式编程语言来说,函数是第一位(first class)的,它可以像其他数据类型一样被使用,那么当它作为函数的参数时,我们需要约定一个语法来描述这个”参数”(实际上是一个函数)的”类型”(实际上应该是这个函数的”元信息“),那么对于一个函数来说,它的”类型“应该怎样去描述呢?从语言的设计者角度来考虑的话,那当然最合理的描述方式是:陈述出这个函数的参数类型和它的返回值类型!这也正是operator: (Int, Int) => Int)所做的!简单明了,合情合理!


数组


scala> val array = new Array[String](3)
array: Array[String] = Array(null, null, null)
scala> array(0) = "This"
scala> array(1) = "is"
scala> array(2) = "mutable"

对于给数组赋值的语句:array(0) = “This”,这里要说明的是:不同于java中的array[0] = “This” 在scala中,[]永远是用来制定参数类型的!


FOR循环


val files = new java.io.File(".").listFiles
    for(file <- files) {
    val filename = file.getName
    if(fileName.endsWith(".scala")) println(file)
}

The only thing that looks different from for loops in Java or C# is the expression file <- files. In Scala this is called a generator, and the job of a generator is to iterate through a collection.

scala> val aList = List(1, 2, 3)
aList: List[Int] = List(1, 2, 3)
scala> val bList = List(4, 5, 6)
bList: List[Int] = List(4, 5, 6)
scala> for { a <- aList; b <- bList } println(a + b)
5
6
7
6
7
8
7
8
9  

scala> val result = for { a <- aList; b <- bList } yield a + b
result: List[Int] = List(5, 6, 7, 6, 7, 8, 7, 8, 9)
scala> for(r <- result) println(r)
5
6
7
6
7
8
7
8
9 

注:for语句的花括号{}并不是必须的,你完全可以使用().


模式匹配:Pattern Matching



模式匹配,示例一:

ordinal(args(0).toInt)
def ordinal(number:Int) = number match {
    case 1 => println("1st")
    case 2 => println("2nd")
    case 3 => println("3rd")
    case 4 => println("4th")
    case 5 => println("5th")
    case 6 => println("6th")
    case 7 => println("7th")
    case 8 => println("8th")
    case 9 => println("9th")
    case 10 => println("10th")
    case _ => println("Cannot do beyond 10")
} 

case _ to match everything else.

模式匹配,示例二:

在下面的这个例子中展示了scala一些内置的预定义的Pattern,专门应用于case上的,例如下面例子中的:f,s, rest

scala> List(1, 2, 3, 4) match {
case f :: s :: rest => List(f, s)
case _ => Nil
}
res7: List[Int] = List(1, 2)  

模式匹配,示例三:

val suffixes = List("th", "st", "nd", "rd", "th", "th", "th","th", "th","th");
println(ordinal(args(0).toInt))
def ordinal(number:Int) = number match {
    case tenTo20 if 10 to 20 contains tenTo20 => number + "th"
    case rest => rest + suffixes(number % 10)
} 

类:Class



What val and var do is define a field and a getter for that field, and in the case of var an additional setter method is also created. When both of them are missing, they’re treated as private instance values, not accessible to anyone outside the class.

对于Class的field的修饰符有如下约定:

  1. 使用var声明field,则该field将同时拥有getter和setter

    scala> class MongoClient(var host:String, var port:Int)

  2. 使用val声明field,则该field只有getter。这意味着在初始化之后,你将无法再修改它的值。

    scala> class MongoClient(val host:String, val port:Int)

  3. 如果没有任何修饰符,则该field是完全私有的。

    scala> class MongoClient(host:String, port:Int)


时间: 2024-10-12 22:07:25

SCALA学习笔记(一)的相关文章

Scala学习笔记及与Java不同之处总结-从Java开发者角度

Scala与Java具有很多相似之处,但又有很多不同.这里主要从一个Java开发者的角度,总结在使用Scala的过程中所面临的一些思维转变. 这里仅仅是总结了部分两种语言在开发过程中的不同,以后会陆续更新一些切换后在开发过程中值得注意的地方.以下列举了部分,但令人印象深刻的Scala语言的不同之处,具体的代码演示样例及具体阐述见下文. ? Scala中可直接调用Java代码,与Java无缝连接. 语句能够不用";"结束.且推荐不适用";". 变量声明时以var或va

原创:Scala学习笔记(不断更新)

Scala是一种函数式语言和面向对象语言结合的新语言,本笔记中就零散记下学习scala的一些心得,主要侧重函数式编程方面. 1. 以递归为核心控制结构. 实现循环处理的方式有三种:goto,for/while,递归,其中用goto实现循环已经在现代语言中被放弃,而for/while形式的结构化编程成为主流,而递归作为另一种方案,则长期只流行在函数式编程的小圈子中. 递归被主流编程界所担心的主要是过深的调用栈,甚至以前的课堂上我们还亲自尝试过将递归改写为循环,但是现代函数式编程语言中,通过尾递归(

Scala学习笔记及与Java不同之处总结-从Java开发人员角度

Scala与Java具有许多相似之处,但又有许多不同.这里主要从一个Java开发人员的角度,总结在使用Scala的过程中所面临的一些思维转变.这里只是总结了部分两种语言在开发过程中的不同,以后会陆续更新一些切换后在开发过程中值得注意的地方.下面列举了部分,但令人印象深刻的Scala语言的不同之处,具体的代码示例及详细阐述见下文. ? Scala中可直接调用Java代码,与Java无缝连接: 语句可以不用";"结束,且推荐不适用";": 变量声明时以var或val开头

Scala学习笔记一之基础语法,条件控制,循环控制,函数,数组,集合

前言:Scala的安装教程:http://www.cnblogs.com/biehongli/p/8065679.html 1:Scala之基础语法学习笔记: 1:声明val变量:可以使用val来声明变量,用来存放表达式的计算结果,但是常量声明后是无法改变它的值的,建议使用val来声明常量: 声明var变量:如果要声明可以改变的引用,可以使用var变量,声明的常量的值可以改变. 3:指定类型:无论声明val变量还是声明var变量.都可以手动指定其类型,如果不指定,scala会自动根据值,进行类型

Scala学习笔记-环境搭建以及简单语法

关于环境的搭建,去官网下载JDK8和Scala的IDE就可以了,Scala的IDE是基于Eclipse的. 下面直接上代码: 这是项目目录: A是scala写的: package first import scala.collection.mutable.ListBuffer object A { def main(args: Array[String]) { print("Hello,Scala");//学习程序设计的第一句 println("---");//pr

scala 学习笔记(04) OOP(上)

一.主从构造器 java中构造函数没有主.从之分,只有构造器重载,但在scala中,每个类都有一个主构造器,在定义class时,如果啥也没写,默认有一个xxx()的主构造器 class Person { var name: String = _ /** * 从构造器 * @param name */ def this(name: String) = { this //注意:从构造器,必须先调用主构造器 this.name = name; } override def toString = { "

Scala并发编程实战初体验及其在Spark源码中的应用解析之Scala学习笔记-56

package com.leegh.actor import scala.actors.Actor /** * @author Guohui Li */object First_Actor extends Actor { def act() { for (i <- 1 to 10) { println("Step : " + i) println(Thread.currentThread().getName) Thread.sleep(2000) } }} object Seco

Scala中复合类型实战详解之Scala学习笔记-44

package com.leegh.parameterization import com.leegh.parameterization.Compound_Type /** * @author Guohui Li */ trait Compound_Type1;trait Compound_Type2;class Compound_Type extends Compound_Type1 with Compound_Type2object Compound_Type { def compound_

Scala学习笔记-11

package com.leegh.oop import scala.io.Source /** * @author Guohui Li */object FunctionOps { def main(args: Array[String]) { val width = args(0).toInt for (arg <- args.drop(1)) processData(arg, width) var increase = (x: Int) => x + 1 increase(10) inc

Scala 学习笔记(2)之类和对象

Scala 的类大抵和 Java 是类似的,简单的例子如下: class MyClass { var myField : Int = 0; def this(value : Int) = { this(); this.myField = value; } def getMyField() : Int = { return this.myField; } def addToMyField(value : Int) { this.myField += value; } } 如果好奇,可以把编译后的代