首页 > 其他分享 >控制结构和函数

控制结构和函数

时间:2023-08-13 09:25:48浏览次数:45  
标签:函数 val Scala 控制结构 else 参数 表达式

第2章 控制结构和函数

2.1 条件表达式

在scala中if/else表达式有返回值,返回值是if或者else最后一行的值。例如:

if(x > 0) 1 else -1

上述表达式的返回值是1或-1,具体是哪一个取决于x的值。

if表达式的类型推断,由于if表达式是有值的,而if和else子句的值类型可能不同,此时if表达式的值是什么类型呢?Scala会自动进行推断,取两个类型的公共父类型。

if(age > 18) 0 else 1

自动推断返回值类型为 Int 类型

  if(age > 18) “adult”else 1 

自动推断返回值类型为 Any

如果if 后面没有跟else,则默认else的值是Unit,也用()表示,类似于java中的void或者null。例如:

val age = 12; if(age > 18) "adult",此时就相当于if(age > 18) "adult" else () 。

示例代码:

 val lbs = 150.0
    val height = 1.83
    val weightStatus = {
      val bmi = lbs/(height * height)
      val result = if(bmi < 18.5) "Underweight"
      else if(bmi < 25) "Normal weight"
      else "Overweight"
      print(result);
    }

2.2 语句终止

在单行中写下多个语句,需要用分号隔开

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

在写较长的语句,需要分两行来写的话,要确保第一行以一个不能用做语句结尾分符号结尾,通常来说是操作符

s = s0 + 
	v * t

2.3 块表达式和赋值

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

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

2.4 输入与输出

输出有print和println函数,后者在打印完内容后会追加个换行符。例如:

print("Answer:")
println(42)
或
println("Answer:" + 42)
或
println("Answer:%d", 42)

输入有readLine函数从控制台读取一行输入。它可以带一个参数作为提示字符串,如过要读取的是数字、Boolean或字符,可以用readint、readDouble、readByte、readShort、readLong、readFloat、readBoolean或者readChar,但是不带参数。

2.5 循环

2.5.1 while循环

var  temp = readInt                            scala.io.StdIn.readInt()
while(temp > 0) {
	println(temp)
    temp -= 1
}

2.5.2 for循环

for(c <- "Hello World") {
      print(c)
}

2.5.3 yeild关键字,允许创建一个值去记录每一次迭代

for(c <- "Hello World") yield c

2.6 高级for循环和for推导式

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

注意:在if之前并没有分号

如果for循环的循环体以yield开始,则该循环会构造出一个集合,每次迭代生成集合中的一个值:

for (i <- 1 to 10) yield i % 3

这类循环叫做for推导式。

2.7 函数

优点:更好的管理程序;抽象和复用代码;Scala 提供了许多Java中没有的定义函数的方式。除了作为对象成员函数的方法之外,还有内嵌在函数中的函数,函数文本和函数值

def + 方法名(参数名 : 参数类型) : 返回类型 = {
//block内最后一行为返回值
}

当返回值为Unit时可以定义为: def 方法名(参数名 : 参数类型) {}

没有参数的方法可以不带圆括号

Scala没有静态方法,通过object来实现

Scala中定义函数时,需要定义函数的函数名、参数、函数体

Scala要求必须给出所有参数的类型,但是不一定给出函数返回值的类型,只要右侧的函数体中不包含递归的语句,Scala就可以自己根据右侧的表达式推断出返回类型

image-20200112204452252

Scala 的函数是一等公民,不仅可以定义后被调用,还可以把它写成匿名的字面量,然后作为值进行传递。

函数的字面量被编译进类,并在运行期间实例化为函数值。

字面量是指=>右端的部分(即:函数的表达式)例如 x:Int => x 7 则x7 是函数字面量;函数字面量和函数值区别在于存在于源代码还是对象运行期间

任何函数值都是扩展了Scala 包的若干FunctionN特质之一的类的实例,如Function0 是没有参数的函数,每个FunctionN特质有一个apply 方法来调用函数。

如果想让函数字面量更加整洁,可以把下划线当做一个或更多的参数占位符,只要每个参数在函数字面量内仅出现一次。

值函数:Scala的语法规定,将函数赋值给变量,并且在函数后面加上空格和下划线的形式

匿名函数:Scala中,不命名的函数。

高阶函数:接收其他函数作为参数的函数,被称作高阶函数
高阶函数的另外一个功能是将函数作为返回值
高阶函数可以自动推断出参数类型,调用时不需要写明类型①
对于只有一个参数的函数,调用时还可以省去其小括号②
如果仅有的一个参数在右侧的函数体内只使用一次,则还可以将接收参数省略,并且将参数用_来替代(下图中 main 函数分别展示了高阶函数的这些中写法,大家要熟悉)

image-20200113113243664

部分应用函数:是一种表达式,无需提供部分应用函数所有的参数,只提供部分或者不提供

def add(x: Int, y: Int) = x + y

我们定义add 函数,将add 函数的部分应用表达式赋值给a,实例化一个带有两个缺失值的函数值并把新的函数值索引给变量a,当把函数值a应用于两个参数之上时,它将回头调用add并传入两个参数

 val a = add _ //未使用所有参数
 a(4,5)

原理:名为a的变量指向一个函数值对象。这个函数值是由Scala编译器依照偏应用函数表达式add _,自动产生的类的一个实例。编译器产生的类有一个apply方法带两个参数。Scala编译器把表达式a(4,5)翻译成对函数值的apply方法的调用,传入4,5。因此a(4,5) = a.apply (4,5)

函数 VS 方法:

参数列表对于方法是可选的,但是对于函数参数列表是强制的
方法可以没有参数列表,参数列表也可以为空;而函数必须有参数列表(也可以为空)。
方法名意味着方法调用,但函数名却代表的是函数自身。
方法可以自动(称之ETA扩展)或手动强制转换为函数;但是函数不可以转换成方法。

2.8 参数

默认参数:在定义函数时,被赋予初值的参数

带名参数:在调用函数时,在提供参数值的时候指定参数名

变长参数:在参数数据类型后面加上*

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

你可以使用任意多的参数来调用该函数。

_:用于将一个值的序列转化成参数序列
用法:s = sum(1 to 5: _)

2.9 过程

scala对于不返回值的函数有特殊的表达法。如果函数体包含在花括号中但没有前面的=,那么返回类型就是Unit,这样的函数叫过程。过程不返回值

2.10 懒值

当val被声明为lazy时,它的初始化将被推迟,直到对他首次取值

每当我们访问懒值都会调用一个以线程安全的方式检查该值是否已被初始化的方法

2.11 异常

单行Scala 异常机制和Java 类似,当抛出异常时,当前运算被截止

抛出的对象必须是 java.lang.Throwable 的子类

Scala 没有“受检”异常不需要声明函数可能会抛出某种异常

Scala 中捕获异常的组合通常是 try{…} catch{…} 或者是 try{…} finally{…}它们是互补的

try{…} catch{…} finally{…} 其实是 try{ try{…} catch{…} } finally{…} 的等价形式

image-20200112214555623

try finally 组合 无论是否发生异常都能释放资源

如果URL 构造或openStream方法抛出异常,这样try代码块和finally 代码块都不会执行(这也没什么不好in 未初始化不需要close)

image-20200113091929791

标签:函数,val,Scala,控制结构,else,参数,表达式
From: https://www.cnblogs.com/simpleness/p/17626129.html

相关文章

  • 5.0 Python 定义并使用函数
    函数是python程序中的基本模块化单位,它是一段可重用的代码,可以被多次调用执行。函数接受一些输入参数,并且在执行时可能会产生一些输出结果。函数定义了一个功能的封装,使得代码能够模块化和组织结构化,更容易理解和维护。在python中,函数可以返回一个值或者不返回任何值,而且函数的参......
  • 第二章 运算符和数学函数
    第二章运算符和数学函数2.1数学运算符:创建序列(两头都会包含)>x<-2:4>x[1]234+加>1+1[1]2-减>2-1[1]1*乘>1*2[1]2/浮点数除法>3/2[1]1.5%/%整数除法>3%/%2[1]1%%余数>3%%2[1]1^或**求幂>2^2[1]4>2**2[1]4......
  • 第五章 函数和正则
    第五章函数和正则5.1函数5.1.1内置函数5.2.1创建和调用函数定义函数的格式为:函数名<-function(参数列表){​ 函数体​ return返回值}注意:没有显式的“return”关键字声明应该从函数返回哪个值。在R中,函数中计算的最后一个值将自动返回。hypotenuse<-function(x,......
  • 学习go语言编程之函数
    函数定义函数的基本组成:关键字func,函数名,参数列表,返回值,函数体,返回语句。示例如下:funcAdd(aint,bint)(retint,errerror){ ifa<0||b<0{ err=errors.New("shouldbenon-negativenumbers") return } returna+b,nil//支持多重返回值}如果参......
  • 数论函数小计
    1.基础数论函数定义:数论函数,就是值域为整数(陪域为复数)的函数狄利克雷卷积两个数论函数的狄利克雷卷积是一个新的函数比如\(f(n)\),\(g(n)\)它们的卷积就是\(f*g\)怎么卷呢?定义:\(\large{(f*g)(n)=\sum\limits_{d|n}f(n)g(n/d)}\)举个例子:\((f*g)(12)=f(1)*g......
  • 线性筛与欧拉函数
    很萌很可爱!就是把纸质笔记上letex写在这里有亿点慢线性筛埃氏筛,\(O(n\log\logn)\),思路是⌈标记所有质数的倍数⌋这样每个合数可能会被标记好几次,我们改进一下,让每个合数只有一种被标记的方式,即⌈最小质因子*常数⌋具体而言,⌈枚举\(2\tox\)把当前数\(i\)跟......
  • 区间半群查询与 Ackermann 函数
    最近在思考半在线卷积的复杂度有没有可能进一步优化,决定先理清类似的问题以寻求经验.一区间合并如果询问的时候不能进行半群运算,显然我们需要在预处理阶段处理所有答案,必须进行\(O(n^2)\)次计算.二区间合并如果询问的时候可以进行一次半群运算,则可以把序列每次在中......
  • 无涯教程-Perl - package函数
    描述此函数将当前符号表的名称更改为NAME。包名称的范围一直到封闭块的末尾。如果省略NAME,则没有当前包,并且所有函数和变量名称都必须使用其完全限定的名称声明。语法以下是此函数的简单语法-packageNAMEpackage返回值此函数不返回任何值。要了解package关键字,......
  • 无涯教程-Perl - pack函数
    描述此函数对LIST中的表达式求值并将其打包为EXPR指定的二进制结构。使用下表中显示的字符指定格式-每个字符可以可选地跟一个数字,该数字指定要打包的值的类型的重复计数。根据格式,该值是半字节,字符或什至位。*的值重复*,因为LIST中保留了尽可能多的值。可以使用拆包功能将......
  • 无涯教程-Perl - ord函数
    描述此函数返回EXPR指定的字符的ASCII数值,如果省略则返回$_。例如,ord('A')返回值为65。语法以下是此函数的简单语法-ordEXPRord返回值该函数返回整数。例以下是显示其基本用法的示例代码-#!/usr/bin/perl-wprint("ord()",ord('G'),"\n");执行上述代码后......