zoukankan      html  css  js  c++  java
  • Scala学习笔记(2)

    一、控制结构和函数

    ---------------------------------------------------------------

    1、条件表达式

     (1) 在Scala中if/else的表达式都是有值的,这个值就是跟在if或者else之后的表达是的值

      eg: if(x >0) 1 else -1  //上面表达式的值是1或者-1,具体是哪个值取决于x的值

      

     (2) 可以将if/else表达式的值赋给变量

      val s = if (x > 0) 1 else -1   <===>if(x>0) s = 1 else s =-1  //相对而言,前面的一种写法会更好,因为其可以用来初始化一个val,而在后面的s必须是var类型,这个地方x是常量不能再进行赋值了

      java表达式:x>0?1 : -1    //Java或C++  <===>if(x > 0 )1 else -1

      (3)在Scala中,每个表达式都有一个类型。举例来说,表达式if(x>0) 1 else -1 的类型是Int,因为这里的两个表达式都是Int

        而:if (x>0) "positive" else -1   //这个表达式的类型是两个分支类型的公共超类。这里第一个分支是java.lang.String

        而另外一个 分支是Int类型。所以这里的公共超类是Any

        这里如果else部分缺失了:if (x>0) 1    //那么有可能if语句没有输出值。但是在Scal中,每个表达式都应该有某种值,这个问题的解决方案是引入一个Unit类,写作()。

        不带else的if语句等同于if (x> 0 ) 1 else ()  //()表示的是"无有用值"的占位符,可以将Unit当做Java或C++中的void

      (4)注意:REPL比起编译器来更加的"近视",在同一时间只能看到一行代码。

          eg: if(x>0) 1

            else if (x==0) 0 else -1    //这里REPL会执行if(x>0) 1 ,然后就显示结果,而之后看到接下来的    else    关    键    字  就会不知所措

        如果想在else前面换行的话,需要用到花括号

        if(x > 0){1

          } else if (x==0) 0 else -1 

        如果想在REPL中粘贴成块的代码,而又不想近视问题,可以使用粘贴模式。键入:paste,把近视代码粘贴进去,然后按下Ctrl + D。这样REPL会把整个代码块当做一个整体来进行分析

      (5)条件表达式,scala的表达式有值,是最后一条语句的值

        scala>val x =1 ;

        scala > val b = if (x>0) 1 else -1 ;

      (6)val xx = if(x>0) 1 else "hello"  //这个地方的返回值是Any类型  xx:Any =1,Any是Int和String的创造类

        参数的强转: 1.toString    //将数值类型的转换成字符串类型String类型  

              "1000".toInt   //将字符串类型转换成Int类型

      (7)赋值语:val y = (s =1 )    //赋值语句为空,y:Unit =()  类似于java中的void

      (8)粘贴模式:scala>:paste

              if(x>0) {

               1  } else -1

    //      ctrl + D  //退出粘贴模式

      (8)java语言的编码运行过程:*.java ----->*.class----------->程序

    2、语句终止:Scala与其他的脚本语言相类似,行尾的位置不需要分号。在}、else以及类似的位置也不需要写分号,只要能从上下文明确的判断出这里是语句的终止就可以

      (1)如果在单行中能够写下多个语句,就需要用分号将他们分割开来

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

      (2)如果写较长的语句,需要分成两行来写的话,就需要确保第一行以一个不能用作语句结尾的符号作为结尾,一般来说是比较好的选择是操作符:

      s = s0 +(v - v0)* t +

        0.5*(a-a0)*t*t

      (3)Scala程序员们更加倾向于使用花括号来进行相关的处理:

        if(n > 0){

          r = r*n

          n -=1

         }      //这个地方可以知道,以{结束的行很清楚的表示了后面还有很多的内容

    3.块表达式和赋值

      在java中快语句是包含在{}中的语句序列。当需要在逻辑分支或循环中放置多个动作的时候,可以使用快语句。

      在Scala中,{}块包含一系列的表达式,结果也是一个表达式。快中最后一个表达式的值就是块的值

      eg:val distance = {val dx = x -x0 ; val dy = y -y0 ; sqrt (dx * dx + dy * dy)}

      {}块的取值取其最后一个表达式,在此处粗体标出。变量dx和dy仅作为计算所需的中间值

      在Scala中,赋值动作本身是没有值的,或者说,他们的值是Unit类型的,Unit类型等价于java中的void,而这个类型只有一个值,写作()。一个以赋值语句结束的块,比如{r =r * n; n -=1)的值是Unit类型的

       Unit<===>void

    4、输入和输出

      (1).打印一个值,需要用print或者println函数进行相关的打印,而后者在打印完成后会追加一个换行符。

        print("answer:")    //打印

        println(43)      //换行打印

      //输出

      Scala>print("hellp")

      Scala>println("hello")

      Scala>val password = readLine("请输入密码");

    5、循环

      Scala拥有和java相同的while和do循环

      通过粘贴模式来写循环。(while)

    var i = 0;
    while
    (n>0){ r= r*n n-=1 }

    通过Scala语言打印出99乘法表

      

    var i = 1;
    while(i<10){
      var j = 1;
      while(j<=i){
      print(i+"*"+j+"="+(i*j)+"    ");
      j+=1;          
      }     
      println();
      i+=1;       
    }

      百钱买百鸡问题

    //百钱买白鸡
    100块钱买100只小鸡
    公鸡:5块钱/只
    母鸡:3块钱/只
    小鸡:1块钱/3只

    var cock=0;
    while(cock <= 20){
    var hen = 0 ;
    while(hen <=100/3){
    var chicken =0;
    while(chicken<=100){
    var money=cock*5 + hen*3 +chicken*(1/3);
    var mount = cock + hen + chicken;
    if(money==100 && mount==100){
    println("cock:"+cock+","+"hen:"+hen+","+"chicken:"+chicken);
    }
    chicken+=3;
    }
    hen+=1;
    }
    cock+=1;
    }

    
    
     

    Scala加载Scala类的方法:load d:scalauy.scala

      (2)for循环

      

    for(x<-1 to 10) println(x)
    语法:
        for(i<- 表达式)    //这个地方1 to n 这个调用返回1到n之间的区间的Range
    //让变量i便利<-右边的表达式的所有制。至于这个便利具体如何执行,取决于表达式的类型。

      在便利字符串或者数组的时候,通常需要使用0到n-1的区间。这个时候可以用util方法而不是to方法。util方法返回一个并不包含上限的区间。

      

    val s ="hello"
    var sum = 0
    for(i <- 0 util s.length){    sum +=s(i)}
    println(sum);
      

    可以使用breaks对象的break方法

    6、可以使用变量<-表达式的形式提供多个生成器,用分号将其分隔开来。

      for高级循环

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

      这个地方每一个生成器都可以带一个守卫,以if开头的Boolean表达式:

      

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

    如果for循环的循环体外面以yield开始,则循环会构造一个集合,每次都迭代集合中的一个值

      

    for(i < -1 to 10) yeild i%3   //这样的for循环叫做for循环推倒式

    7、函数

    Scala除了方法之外还支持函数。方法对对象进行操作,函数不是,如果要定义函数,需要给出函数的名称、参数和函数体

      

    def abs(x:Double)=if(x>=0) x else -x

    如果函数体需要多个表达式完成,可以用代码块。快中最后一个表达式就是函数的返回值。

    def fac(n:Int)={
        var r =1
        for(i<- 1 to n) r= r*i
        r
       }

    本例中返回值是r,但是没有return 这个关键词

    但是对于递归函数,我们必须制定返回值类型。

      def fac(n:Int):Int=if(n<=0) 1 else n*fac(n-1)  //这个地方的递归函数必须制定返回值类型,如果没有进行指定,Scala编译器就没有办法校验n*fac(n-1)的数据类型了

      定义函数:

      def add (a:Int,b:Int):Int = {

        var c =a+b ;

        return c;

    }

    在:paste模式下进行粘贴,最后会得到add(a:Int,b:Int)Int,即是参数类型是Int型,返回值类型也是Int型

      定义递归:

      def fac(n:Int):Int= if(n==1) 1 else n*fac(n-1);    //定义了n的阶乘,递归的函数必须显示定义返回值类型

      8.默认参数和带名参数

      (1)eg:def decorate(str:String,left:String="[",right:String="]")= left+str+right;

      如果调用decorate("hello")  ===>["Hello"]

      或者:def decorate(prefix:String,str:String,suffix:String)={  //默认不带参

        prefix+str+suffix    

      }

      //这个地方的调用:最少要带上两个参数,decorate("hello","world");最终把最后的括号带上了

      //或者指定给哪个参数进行传参,decorate(str="hello")

      //或者给其他的参数进行相关的传参:scala>decorate(str="hello",prefix="<<"。最后的返回值是<<hello[]]

      def decorate(prefix:String="[[",str:String,suffix:String="]]")={  //默认带参数的

        prefix+ str+suffix

      }

      调用函数decorate("[[","hello","]]") ==============>[[hello]]

      (2)如果相对参数的数量的值不够,参数会从后面诸葛应用进来,如decorate("Hello",">>>")会使用right参数的默认值,

       得到">>>[Hello]"

    def sum(args:Int*)={
        var result = 0
        for(arg <- args) result+=arg
        result
    }

      (3)在提供参数值的时候指定参数名。如:

        decorate(left="<<<",str="Hello",right=">>>")    //最后的结果是<<<Hello>>>

      (4)带名参数可以让函数更加可读。

      (5)函数的默认值和命名参数

        scala>def decorate(prefix:String,str:String,suffix:String)={

          prefix + str +sufix

      }

    9.变长参数

     (1)边长参数用法例子 

    def sum(args:Int*)={
      var result = 0 
      for(arg<-args)  result+=arg
      result          
    }

      val s = sum(1,4,9,16,25)  //这个地方函数得到的是一个类型为Seq的参数

      (2)如果已经有一个值的序列,则不能直接将其传入函数。如:var s =sum(1 to 5)  //错误

      val s = sum (1 to 5)  //错误,这个地方要注意,如果sum函数传入的是单个参数,那么参数必须是单个的整数,而不是一个整个的区间。解决的办法是告诉编译器,希望这个参数被当做参数序列进行处理。追加:_*,如下所示:

      val s =sum(1 to 5:_*)  //这个地方将1 to 5当做参数序列进行处理

      (3)在递归定义中会用到上面的语法:

        def recursiveSum(args:Int*):Int={    //在这里序列head是首个元素,而tail是所有其他元素的序列,这又是一个Seq,我们用_*来转换成参数序列

          if(args.length==0) 0 

          else args.head + recursiveSum(args:tail:_*)

      }

      

      (4)参数当做参数序列进行处理

    def sum1(args:Int*):Int={
        if(args.length==0) 0
        else args.head+sum1(args.tail_*)
    }

    scala>add(1 to 10)    //错误

    scala>add(1 to 10:_*)  //将1 to 10当做序列

    10.过程:如果函数体包含在花括号中但是没有前面的=号,那么返回值类型就是Util。这样的函数成为过程

        过程不返回值,我们调用它仅仅是为了副作用

        (1)也可以进行这样的方式进行相关的定义:def box(s:String):Unit={

            ................

          }

    def box(s:String){    //仔细看:这个地方没有=号
        var border="-" * s.length +"--
    "
        println(border+"|"+s+"
    "+border)
    }

    11.懒值

      当val被声明为lazy的时候,它的初始值将被推迟,知道我们首次对其进行取值

      lazy val words = 

    12.异常处理

      try{

        "hello".toInt;

      }catch{

        case _:Exception =>print("xxx");

        case ex:java.io.IOException=>print(ex)

      }

      _      //通配符

      java.io._    //通配相当于*

      :_*      //1 to10:_*,转成序列

  • 相关阅读:
    atitit.  web组件化原理与设计
    Atitit.git的存储结构and 追踪
    Atitit.git的存储结构and 追踪
    atitit.atiHtmlUi web组件化方案与规范v1
    atitit.atiHtmlUi web组件化方案与规范v1
    Atitit.设计模式-----触发器模式 trigger  详解
    Atitit.设计模式-----触发器模式 trigger  详解
    Atitit.web ui  组件化 vs  mvc
    Atitit.web ui  组件化 vs  mvc
    Atitit..css的体系结构
  • 原文地址:https://www.cnblogs.com/bigdata-stone/p/9632631.html
Copyright © 2011-2022 走看看