Scala学习笔记:面向对象

2019-10-18 15:01 来源:未知

为方便阅读,以下呈现的编写翻译后的class文件有做适度调节,且超过1/3的main函数的object编写翻译内容并未有出示

变量定义

Scala 定义了两体系型的变量val和var,val类似于Java中的final变量,一旦初阶化之后,不得以另行复制(咱们能够称它为常变量)。而var类似于平日的非final变量。能够恣心纵欲重新赋值。

举例说定义叁个字符串常变量:

scala> val msg="Hello,World"

msg:String= Hello,World

那些表明式定义了八个msg变量,为字符串常量。它的品种为string(java.lang.string)。 能够看到大家在概念那个变量时并无需像Java同样定义其品种,Scala 能够依据赋值的内容推算出变量的门类。那在Scala语言中变为“type inference”。当然即便您愿意,你也能够利用和Java同样的秘籍,显明内定变量的花色,如:

scala> val msg2:String="Hello again,world"

msg2:String= Hello again,world

而是这样写就显得不像Scala风格了。另外Scala语句也无需以分集团结尾。 如若在指令行中须求分多行输入,Scala解释器在新行前边显示|,表示该行接着上一行。比方:

scala> val msg3=    

           |"Hello world 3rd time"

msg3:String= Hello world 3rd time

Generic

相比较轻便的例证

class Valuable(value:Int) {

    def getValue(): Int = value
}

object Comparable {

    def add[E <: { def getValue():Int }](l: E, r: E):Int = l.getValue() + r.getValue()

    def main(args: Array[String]): Unit = {
        println(add(new Valuable(1), new Valuable(2)))
    }
}

// output:
// 3

Scala中的while循环

上边包车型大巴代码应用while达成三个巡回:

var i=0

while(i < args.length) {  println (args(i))  i+=1}

那边要留意的是Scala不扶持++i和i++运算符,因而要求运用i += 1来加一。 这段代码看起来和Java代码差十分的少,实际上while也是贰个函数,你活动可以行使scala语言的扩大性,达成while语句,使它看起来和Scala语言自带的根本字同样调用。

Scala访谈数组的语法是选取()而非[]。

这里介绍了应用while来实现循环,但这种完毕循环的艺术而不是最佳的Scala风格,在下一步介绍使用一种越来越好的法子来幸免通过索引来枚举数组成分。

Trait

trait类似于java中的接口,但支撑部分的落到实处。三个trait实在是被编写翻译成了相应的接口和抽象类多个文本。

trait Singer {

    val song:String = "sunshine"

    def singe(): Unit = {
        println("singing " + song)
    }

    def name(): String
}

class Star extends Singer {

    override def name(): String = {
        return "Lilei"
    }
}

object Star {

    def main(args: Array[String]): Unit = {
        val s = new Star()
        s.singe()
        println(s.name())
    }
}

// output:
// singing sunshine
// Lilei

编写翻译出的class文件:

public abstract interface Singer {

    public abstract void com$study$classdef$witht$Singer$_setter_$song_$eq(String paramString);

    public abstract String song();

    public abstract void singe();

    public abstract String name();
}

public abstract class Singer$class {

    public static void $init$(Singer $this) {
        $this.com$study$classdef$witht$Singer$_setter_$song_$eq("sunshine");
    }

    public static void singe(Singer $this) {
        Predef..MODULE$.println(new StringBuilder().append("singing").append($this.song()).toString());
    }
}

public class Star implements Singer {
    private final String song;

    public String song() {
        return this.song;
    }

    public void com$study$classdef$witht$Singer$_setter_$song_$eq(String x$1) {
        this.song = x$1;
    }

    public void singe() {
        Singer$class.singe(this);
    }

    public Star() {
        Singer$class.$init$(this);
    }

    public String name() {
        return "Lilei";
    }
}

可以见见:

  • 在Star的构造函数中会调用trait的抽象类的static $init$()艺术来初始化从trait承继来的song属性。传承来的song属性被发明到了Star中,与scala中的trait已经淡出了关系。在java中,interface里声明的都以static变量,所以scala那样达成也是很合理的。

Lists

Scala也是三个面向函数的编制程序语言,面向函数的编制程序语言的一个特点是,调用某些方法不该有其他副成效参数一定,调用该办法后,重回一定的结果,而不会去修改程序的其他情形(副功能)。这样做的一个功利是办法和办法之间关联性非常的小,从而艺术变得更牢靠和重用性高。使用那么些法规也就象征就变量的设成不可修改的,这也就防止了八线程访问的互锁难点

前方介绍的数组,它的成分是足以被修改的。假设供给动用不可以修改的种类,Scala中提供了Lists类。和Java的List差别,Scala的Lists对象是不行修改的。它被规划用来满意函数编制程序风格的代码。它有一点点像Java的String,String也是不能修改的,假使急需能够修改的String对像,能够运用StringBuilder类。

比方上边的代码:

val oneTwo =List(1,2)

val threeFour =List(3,4)

val oneTwoThreeFour=oneTwo ::: threeFour

println (oneTwo +" and "+ threeFour +" were not mutated.")

println ("Thus, "+ oneTwoThreeFour +" is a new list")

概念了七个List对象oneTwo和threeFour,然后经过:::操作符(其实为:::方法)将七个列表链接奋起。实际上由于List的不可以修改特性,Scala创造了三个新的List对象oneTwoThreeFour来保存八个列表连接后的值。

List也提供了三个::方法用来向List中增多贰个成分,::方法(操作符)是右操作符,也便是利用::左侧的对象来调用它的::方法,Scala中规定持有以:开端的操作符都是右操作符,由此一旦你协调定义以:初始的秘诀(操作符)也是右操作符。

如上面采取常量创造三个列表:

valoneTowThree =1::2::3:: Nil

println(oneTowThree)

调用空驶列车表对象Nil的::方法 也正是:

valoneTowThree =  Nil.::(3).::(2).::(1)

Scala 的List类还定义此外众多很有用的主意,比方head、last、length、reverse、tail等。这里就不一一表明了,具体能够参照List的文书档案。

class defination

整个class的结构内都是构造函数,构造函数的参数间接跟在评释背后。在new对象的时候,里面包车型地铁装有代码都会推行。

class Person(name: String) {

    println("person info: " + info())    // 这里可以先引用info

    val age: Int = 18
    var hobby: String = "swimming"

    println("person info: " + info())    // 这里申明变量后引用

    def info(): String = {
        "name: %s; age: %d; hobby: %s".format(name, age, hobby)
    }
}

object Person {

    def main(args: Array[String]): Unit = {
        new Person("Lilei")
    }
}

// output:
// person info: name: Lilei; age: 0; hobby: null     <--- 变量都没被初始化
// person info: name: Lilei; age: 18; hobby: swimming

查看编写翻译后的class文件能够领略大约原因:

public class Person {

    private final String name;
    private final int age;
    private String hobby;

    public int age() {
        return this.age;
    }

    public String hobby() {
        return this.hobby;
    }

    public void hobby_$eq(String x$1) {
        this.hobby = x$1;
    }

    public Person(String name) {
        this.name = name;

        Predef$.MODULE$.println(new StringBuilder().append("person info: ").append(info()).toString());

        this.age = 18;
        this.hobby = "";

        Predef..MODULE$.println(new StringBuilder().append("person info: ").append(info()).toString());
    }

    public String info() {
        return new StringOps(Predef$.MODULE$.augmentString("name: %s; age: %d; hobby: %s")).format(Predef$.MODULE$.genericWrapArray(new Object[] { this.name, BoxesRunTime.boxToInteger(age()), hobby() }));
    }

    public static void main(String[] paramArrayOfString) {
        Person$.MODULE$.main(paramArrayOfString);
    }
}

public final class Person$
{
    public static final Person$ MODULE$;

    static {
        new Person$();
    }

    public void main(String[] args) {
        new Person("Lilei");
    }

    private Person$() {
        MODULE$ = this;
    }
}

可以预知,在类的概念中,除了def,其他语句都是各类实施的
而且object表明的变量和艺术都是在三个object_name+$命名的类中以static格局定义出来的

Tuples

Scala中其余三个很有用的器皿类为Tuples,和List不相同的是,Tuples能够蕴涵不等等级次序的数码,而List只好分包同品种的数额。Tuples在艺术需求回到多少个结果时充裕管用。(Tuple对应到数学的矢量的概念)。

就算定义了三个元组,能够使用._和索引来访谈员组的要素(矢量的重量,注意和数组差异的是,元组的目录从1开始)。

val pair=(99,"Luftballons")

println(pair._1)

println(pair._2)

元组的实际上类型决意于它的份量的门类,例如上边pair的门类实际为Tuple2[Int,String],而(‘u’,’r’,”the”,1,4,”me”)的系列为Tuple6[Char,Char,String,Int,Int,String]。

当前Scala支持的元组的最大尺寸为22。假若有亟待,你能够友善强盛更长的元组。

Duck Typing

假诺会鸭子叫,纵然得鸭子。

class Person {

    def singe(): Unit = {
        println("singing")
    }
}

object Main {

    def singe(singer: {def singe():Unit}): Unit = {  // 只要实现的singe方法就可以作为参数
        singer.singe()
    }

    def main(args: Array[String]): Unit = {
        val person = new Person()
        singe(person)
    }
}

// output:
// singing

这里需求专心的是:因为得是鸭子叫,所以措施名也非得一致。

从利用Scala解释器开首

输入自便的Scala表达式,比如输入1+2,解释器显示:res0:Int = 3

那行展现包罗:

    一个由Scala解释器自动生成的变量名或者由你内定的变量名用来指向总结出来的结果(比如res0代表result0变量)

    一个冒号,前面紧跟个变量类型比方Int

    叁个对等号=

    总计结果,本例为1+2的结果3

    resX变量名能够用在之后的表明式中,比如:此时res0=3,如若输入res0 *3,则显示res1: Int =9。

scala的合罗马尼亚(România)语档写得太烂了。不可能,只可以找点资料,也许看scala编写翻译的class文件,反正最后都以java的语法,然后自身计算一下。

Sets和Maps

Scala语言的一个规划目的是让程序猿能够并且使用面向对象和面向函数的点子编写代码,由此它提供的集结类分成了能够修改的会集类和不能修改的会集类两大类型。比如Array总是能够修改内容的,而List总是不得以修改内容的。类似的状态,Scala也提供了二种Sets和Map集结类。

举个例子 Scala API 定义了Set的基Trait类型Set(Trait的定义类似于Java中的Interface,所分歧的Scala中的Trait能够有艺术的兑现),分多少个包定义Mutable(可变)和Immutable(不可变),使用同一名称的子Trait。下图为Trait和类的根基关系:

图片 1

Set

采纳Set的基本格局如下:

varjetSet = Set ("Boeing","Airbus")jetSet +="Lear"println(jetSet.contains("Cessna"))

缺省事态Set为Immutable Set,如若您要求利用可修改的集合类(Set类型),你能够使用全路线来指明Set,举例scala.collection.mutalbe.Set。

Scala提供的别的贰个门类为Map类型,Scala也提供了Mutable和Immutable三种Map 类型,如下图所示。

图片 2

Map

Map的主干用法如下(Map类似于任何语言中的关联数组如PHP)

val romanNumeral = Map (1->"I",2->"II",3->"III",4->"IV",5->"V")

println (romanNumeral(4))

Currying

柯里化。不废话了,看例子。

object Main {

    def currying(left: Int)(middle: Int)(right: Int): Int = left + middle + right

    def main(args: Array[String]): Unit = {
        val two = currying(2)(_)
        println(two(3)(4))

        val towPlusThree = two(3)
        println(towPlusThree(4))
    }
}

// output:
// 9
// 9

函数能够依次传入八个参数,切每传入三个参数就会生成三个可再三应用的新函数。

函数定义

Scala既是面向对象的编制程序语言,也是面向函数的编制程序语言,由此函数在Scala语言中的地位和类是同等级一人的。

上面包车型地铁代码定义了二个粗略的函数求三个值的最大值:

scala>def max(x:Int,y:Int):Int ={    

          |if(x >y) x    

          |else

          | y    

          | }

max: (x: Int, y: Int)Int

Scala函数以def定义,然后是函数的称呼(如max),然后是以逗号分隔的参数。Scala中变量类型是献身参数和变量的背后,以“:”隔断。这种做的三个好处是便于“type inference”。刚最初有一点不习于旧贯(假如您是Pascal技士会觉的很接近)。一样假若函数需求重临值,它的体系也是概念在参数的末端(实际上每一个Scala函数都有再次来到值,只是稍微再次来到值类型为Unit,类似为void类型)。

此外各种Scala表明式都有重回结果(那点和Java,C#等语言区别),比方Scala的if else语句也许有重临值的,因而函数重临结果没有须要采取return语句。实际上在Scala代码应当尽量防止使用return语句。函数的尾声三个表明式的值就能够看作函数的结果作为再次来到值。

长期以来出于Scala的“type inference”特点,本例其实没有需要点名再次回到值的项目。对于大很多函数Scala都能够预计出函数再次来到值的品种,但近期来讲回溯函数(函数调用本身)照旧须要指明重临结果类型的。

上边在概念个“未有”重临结果的函数(别的语言也许称这种无重临值的函数为程式)。

scala> def greet()= println("hello,world")

greet: ()Unit

greet函数的归来值类型为Unit 表示该函数不回去任何有意义的值,Unit类似于Java中的void类型。这种类型的函数首要用来获得函数的“副效能”,比如本函数的副成效是打字与印刷招呼语。

经过能够总括出持续的表征:

  1. 继承class A extends B with C with D事实上能够当作是class A extends << class B with C with D >>,切对于这一个父类class B with C with D:
    1. 多种承袭的首要字with只行使于trait
    2. 当出现多种承继,前边trait发明的习性和方法会覆盖后面包车型大巴类/trait
      谈起底组成的新class,作为class A父类
  2. 父类后续的属性会作为子类独立的习性被引述,且子类不能够通过super引用父类的属性。
  3. 对于措施的继续,一切同java一致

读取文件

选择脚本完毕某些职责,平常要求读取文件,本节介绍Scala读写文件的着力办法。举个例子上边包车型地铁例证读取文件的每行,把该行字符长度增添到行首:

import scala.io.Source

if(args.length>0){

for( line <- Source.fromFile(args(0)).getLines())   

println(line.length+" "+ line)

}

else Console.err.println("Please enter filename")

能够看见Scala引进包的措施和Java类似,也是通过import语句。文件有关的类定义在scala.io包中。 如若急需引进四个类,Scala使用 “_” 而非 “*”.

Hierarchy

主导的继续结构如下图,图片来源于官方网站:

图片 3

hierarchy.png

Object只是AnyRef的一个子类。

Scala脚本

Scala本人是安排性用来编排大型应用的,但它也足以看作脚本语言来实行,脚本为一雨后玉兰片Scala表达式构成以成就有个别职分,比如前边的Hello World脚本,你也足以选取脚本来达成部分诸如复制文件,创立目录之类的职责。

OO: Class & Object

学习辨识函数编制程序风格

Scala语言的四个特点是支撑面向函数编制程序,因而学习Scala的五个重要方面是改变早前的指令式编制程序理念(特别是来源于Java或C#背景的工程师),守旧要向函数式编制程序转换。首先在看代码上要认知哪一类是指令编制程序,哪类是函数式编制程序。实现这种思虑上的变动,不仅会使您形成贰个更好的Scala技术员,同不时间也会扩张你的视线,令你成为八个越来越好的程序猿。

叁个轻易的尺码,假定代码中蕴含var类型的变量,这段代码正是思想的指令式编制程序,要是代码唯有val变量,这段代码就很有极大大概是函数式代码,因而学会函数式编制程序关键是不选用vars来编排代码

来看二个简约的例子:

def printArgs( args: Array[String]):Unit ={   

        var i=0

        while(i < args.length) { println (args(i))

        i+=1}

}

来自Java背景的程序猿起初写Scala代码很有希望写成地点的兑现。大家试着去除vars变量,能够写成跟符合函数式编制程序的代码:

def printArgs( args: Array[String]Scala学习笔记:面向对象。):Unit ={for( arg <- args)      println(arg)}

抑或更简化为:

defprintArgs( args: Array[String]):Unit ={args.foreach(println)}

其一例子也注明了尽量少用vars的益处,代码越来越精简和精通,进而也能够减弱不当的产生。因而Scala编程的多个主导尺度上,能不用vars,尽量不用vars,能不用mutable变量,尽量不要mutable变量,能制止函数的副作用,尽量不发生副成效。

Extends class

语法基本和java相同,有多少个前提供给潜心的:

  1. var类型无法被子类重写
  2. 从父类承继的变量通过一贯援用的法子利用
  3. 无法选取super去调用父类的变量,var和val类型的都无法。
  4. 因为上一些,所以后来对此变量的保有重回值,都以重写后的值,哪怕是调用的父类方法

scala中定义的一而再关系

class Singer(name: String) {

    val prefix:String = "singer: "
    var gender:String = " male"

    def info(): String = {
        prefix + name
    }
}

class Star(name: String) extends Singer(name) {

    override val prefix: String = "star: "

    override def info(): String = {
        prefix + super.info() + gender
    }
}

object Main {

    def main(args: Array[String]): Unit = {
        val star = new Star("Lilei")
        println(star.info())
    }
}

// output:
// star: star: Lilei male

与上述同类的出口其实跟java语言的企盼是差异的。接着在编写翻译出的class文件里找原因:

public class Singer {

    private final String name;

    public String prefix() {
        return this.prefix;
    }

    private final String prefix = "singer: ";

    public String gender() {
        return this.gender;
    }

    public void gender_$eq(String x$1) {
        this.gender = x$1;
    }

    private String gender = " male";

    public String info() {
        return new StringBuilder().append(prefix()).append(this.name).toString();
    }

    public Singer(String name) {
        this.name = name;
    }
}

public class Star extends Singer {

    public Star(String name) {
        super(name);
    }

    public String prefix() {
        return this.prefix;
    }

    private final String prefix = "star: ";

    public String info() {
        return new StringBuilder().append(prefix()).append(super.info()).append(gender()).toString();
    }
}

能够看出:

  1. 父类的个性是经过调用super()举办初叶话的,那一点和java同样
  2. 父类的本性都以private修饰符,对外暴露public的getter。假设子类重写父类的属性,那么相应的getter正是子类重写的点子,且只会再次回到子类的属性值,所以父类的就吐弃了,即子类承接的属性与父类脱离关系

利用项目参数化数组

在Scala中你能够行使new来实例化多个类。当您成立贰个对象的实例时,你能够动用数值或项目参数。如若利用项目参数,它的效用类似Java或.Net的Generic类型。所例外的是Scala使用方括号来指明数据类型参数,而非尖括号。例如:

val greetStrings = new Array[String](3)

greetStrings(0)= "Hello"

greetStrings(1)= ","

greetStrings(2)= "world!n"

for(i<-0to2) print(greetStrings(i))

能够见到Scala使用[]来为数组指明类型化参数,本例使用String类型,数组使用()而非[]来指明数组的目录。个中的for表明式中使用到0 to 2,这么些表达式演示了Scala的三个基本准绳,倘若多个方法独有三个参数,你能够毫无括号和.来调用那些艺术

所以这里的0 to 2, 其实为(0).to(2)调用的为整数类型的to方法,to方法运用一个参数。Scala中有着的大旨数据类型也是目标(和Java不一致),因而0可以有主意(实际上调用的是RichInt的主意),这种唯有三个参数的秘技能够选拔操作符的写法(不用.和括号),实际上Scala中表明式1+2,最后解释为(1).+(2)+也是Int的二个情势,和Java差别的是,Scala对章程的名称未有太多的界定,你可以选取符同盟为艺术的名目。

那边也验证为何Scala中央银行使()来访谈数组成分,在Scala中,数组和别的普及的类定义一样,没有怎么非常之处,当你在某些值后边使用()时,Scala将其翻译成对应对象的apply方法。由此本例中greetStrings(1)其实调用greetString.apply(1)方法。这种表明方法不仅只限于数组,对于任何对象,若是在其背后使用(),都将调用该对象的apply方法。同样的要是对某些使用()的靶子赋值,举例:

greetStrings(0)="Hello"

Scala将这种赋值转变为该对象的update方法, 也正是greetStrings.update(0,”hello”)。由此地点的事例,使用守旧的章程调用能够写成:

val greetStrings =new Array[String](3)

greetStrings.update(0,"Hello")

greetStrings.update(1,",")

greetStrings.update(2,"world!n")

for(i<-0to2) print(greetStrings.apply(i))

从这点来讲,数组在Scala中并不某种特殊的数据类型,和常常的类未有怎么区别。

而是Scala依然提供了伊始化数组的简便的诀窍,举个例子怎么样的例证数组可以选择如下代码:

val greetStrings =Array("Hello",",","Worldn")

此间运用()其实照旧调用Array类的涉嫌对象Array的apply方法,约等于:

val greetStrings =Array.apply("Hello",",","Worldn")

Mixin Class Composition

scala中除了规范的接续,还能够因此with重在字组合trait类型。

class Person(name: String, age: Int) {

    println("person info: " + info())

    def info(): String = {
        "name: %s; age: %d".format(name, age)
    }
}

trait Child {

    println("child info: " + info())

    def info(): String = {
        " I am a child"
    }

    def play(): Unit
}

trait Chinese {

    println("chinese info: " + info())

    def info(): String = {
        "I am a Chinese, %s, %s".format(province(), gender)
    }

    def province(): String = {
        "Hunan"
    }

    val gender: String  = "male"
}

class Student(name: String, age: Int, grade: Int) extends Person(name, age) with Child with Chinese {

    println("student info: " + info())

    override def info(): String = {
        super.info() + " grade: %d".format(grade)
    }

    override def play(): Unit = {}
}

object Student {

    def main(args: Array[String]): Unit = {
        new Student("Lilei", 18, 1)
    }
}

// output:
// person info: I am a Chinese, Hunan, null grade: 1
// child info: I am a Chinese, Hunan, null grade: 1
// chinese info: I am a Chinese, Hunan, null grade: 1
// student info: I am a Chinese, Hunan, male grade: 1

编写翻译的class文件是那般的:

public abstract interface Child {

    public abstract String info();

    public abstract void play();
}

public abstract class Child$class {

    public static void $init$(Child $this) {
        Predef$.MODULE$.println(new StringBuilder().append("child info: ").append($this.info()).toString());
    }

    public static String info(Child $this) {
        return " I am a child";
    }
}

public abstract interface Chinese {

    public abstract void com$study$classdef$Chinese$_setter_$gender_$eq(String paramString);

    public abstract String info();

    public abstract String province();

    public abstract String gender();
}

public abstract class Chinese$class
{
    public static String info(Chinese $this) {
        return new StringOps(Predef..MODULE$.augmentString("I am a Chinese, %s, %s")).format(Predef..MODULE$.genericWrapArray(new Object[] { $this.province(), $this.gender() }));
    }

    public static String province(Chinese $this) {
        return "Hunan";
    }

    public static void $init$(Chinese $this) {
        Predef$.MODULE$.println(new StringBuilder().append("chinese info: ").append($this.info()).toString());

        $this.com$study$classdef$Chinese$_setter_$gender_$eq("male");
    }
}

public class Person {

    private final String name;

    public Person(String name, int age) {
        Predef$.MODULE$.println(new StringBuilder().append("person info: ").append(info()).toString());
    }

    public String info() {
        return new StringOps(Predef$.MODULE$.augmentString("name: %s; age: %d")).format(Predef..MODULE$.genericWrapArray(new Object[] { this.name, BoxesRunTime.boxToInteger(this.age) }));
    }
}

public class Student extends Person implements Child, Chinese {

    private final String gender;

    public String gender() {
        return this.gender;
    }

    public void com$study$classdef$Chinese$_setter_$gender_$eq(String x$1) {
        this.gender = x$1;
    }

    public String province() {
        return Chinese.class.province(this);
    }

    public Student(String name, int age, int grade) {
        super(name, age);
        Child$class.$init$(this);
        Chinese$class.$init$(this);

        Predef$.MODULE$.println(new StringBuilder().append("student info: ").append(info()).toString());
    }

    public String info() {
        return new StringBuilder().append(Chinese.class.info(this)).append(new StringOps(Predef..MODULE$.augmentString(" grade: %d")).format(Predef..MODULE$.genericWrapArray(new Object[] { BoxesRunTime.boxToInteger(this.grade) }))).toString();
    }

    public static void main(String[] paramArrayOfString) {
        Student..MODULE$.main(paramArrayOfString);
    }

    public void play() {}
}

能够看出,那只是后边extends和trait三种景况的复合版。在子类student的构造函数中,会挨个推行super()withtrait的$init$()方法。结合前边trait的兑现,可见迟早是后一个父类/trait的变量的值会作为新值,赋值给子类的同名变量。
并且从info()的兑现能够见见super援用被翻译成了Chinese,也正是后二个父类/trait定义的主意也会覆盖前二个。

foreach 和 for 来促成迭代

第五步使用while来落实循环,和平运动用Java实现无太大差别,而Scala是面向函数的言语,更好的点子是使用“函数式”风格来编排代码。例如上面的巡回,使用foreach方法如下:

args.foreach(arg => println(arg))

该表达式,调用args的foreach方法,传入二个参数,这些参数类型也是二个函数(lambda表达式,和C#中概念类似)。这段代码能够再写的简洁些,你能够行使Scala支持的缩写方式,尽管贰个函数独有叁个参数并且只含有一个表明式,那么您没有需求明显指明参数。由此地点的代码能够写成:

args.foreach( println)

Scala中也提供了一个名字为“for comprehension”,它比Java中的for功能更刚劲。“for comprehension”(可称之为for表明式)就要背后介绍,这里先使用for来促成前边的事例:

for(arg <-args)  println(arg)

TAG标签:
版权声明:本文由32450新蒲京网站发布于葡萄游戏厅_体育游戏,转载请注明出处:Scala学习笔记:面向对象