定义自己的控制结构,使它语言内置的用法一样

package exp

object Main {
def enableCustomerIF = false;
def main(args: Array[String]): Unit =
IF(1 / 0 == 0) // 这里就不用写 IF(()=>3>2)(()=>println("hello");
{//这不是语言内置的IF,大括号可不能省略
List("hello","world") foreach println;
} //()=>Boolean 替换成 =>Boolean 就可以实现在不传递参数时省略掉()=>了,为避免歧义要在:与=>之间多留一些空格
def IF(condition: => Boolean)(op: => Unit): Unit = //如果 condition 的类型定义成 Boolean表达式 而不是 =>Boolean的函数的话 禁用 enableCustomerIF 也会报错
if (enableCustomerIF && condition) //condition 是函数调用,因此1/0==0在 enableCustomerIF=false时不会执行
op; //op的定义如果是()=>Unit 执行时就要带括号了
}

定义类的可读\写属性

package exp
object Main {
def main(args: Array[String]): Unit =
{
val s = new Stu;
s.age = 10;
println(s.age);
}
} class Stu {
private var n = "";
private var g = 0; def name = this.n;
def name_=(x: String): Unit = this.n = x;//这个定义更标准,生成的代码也很简单 def age = this.g;
def age_= = this.g = _: Int;//这个定义看上去很简单,更函数式,但是不好理解生成的代码更复杂
}

模式匹配实现的表达式解析

package exp {
object Main {
def simplifyTop(ex: Expr): Expr = ex match {
case UnOp("-", Var(x)) => Var("-" + x);
case UnOp("-", UnOp("-", e)) => simplifyTop(e);
case BinOp("+", e, Number(0)) => e;
case BinOp("*", e, Number(1)) => e;
case BinOp("+", Var(x), Var(y)) => Var(x + y);
case BinOp("+", a, b) => BinOp("+", simplifyTop(a), simplifyTop(b))
case _ => ex;
} def main(args: Array[String]): Unit =
{
val x = simplifyTop(BinOp("+", Var("x"), Var("y")));
println(x);
} abstract class Expr;
case class Var(name: String) extends Expr;
case class BinOp(op: String, left: Expr, right: Expr) extends Expr;
case class Number(num: Double) extends Expr;
case class UnOp(op: String, arg: Expr) extends Expr;
} }

foreach 迭代器和 for (p <- x) 循环迭代是不太一样的

object Main {

    def main(args: Array[String]): Unit =
{
val x = 1 to 10;
var i = 0;
x.foreach {
// i = i+1; 放在这里只执行一次 , foreach 和 for(p <- x) 迭代器还是不一样的
p =>{
i = i + 1; //放在这里会执行10次
println(p);
}
} println(i) i = 0;
for (p <- x) {
i = i + 1; //执行10次
println(p);
}
println(i);
} }

  

  

package exp
{
object Main { def main(args: Array[String]): Unit = { //数组传递给可变参数 :_*
def sum(x:Int*)=x.sum;
println(sum(Array(1,2,3):_*)) //匹配数组或列表多个元素 _*
val Array(a,_,b,_*) = Array(1,2,3,4,5);
println(b); val List(c,_,d,_*) = List(1,2,3,4,5,6)
println(d); //模式匹配上变量绑定 @ case UnOp("abs",e@UnOp("abs",_)) => e
} }
}

 

Option 类型的使用

package exp
{
object Main {
def main(args: Array[String]): Unit = {
div(8,1) match{
case None => println("none");
case Some(y) => println(y);
}
} def div(x:Int,y:Int):Option[Int] = if(y==0) None else Some(x/y)
}
}

  

各种格式的函数定义

val foo : Int=>Int = x => x match {
case 0 => 0;
case x => x+1;
} val foo1 : Int=>Int = _ match {
case 0 => 0;
case x => x+1;
} val foo2 : Int=>Int ={ //能省略掉match的只有这一种情况,指定函数类型变量,在case中直接用样本定义函数
case 0 => 0;
case x => x+1;
} val foo3 = (x:Int) => x match {
case 0 => 0;
case x => x+1;
} def foo4(x:Int):Int = x match {
case 0 => 0;
case x => x+1;
} def foo5(x:Int):Int = {
x match
{
case 0 => 0;
case x => x+1;
}
}

  

定义返回函数的函数

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

            val f = (x:Int) => (y:Int)=>x+y;
println(f(3)(2)); val g:Int=>Int=>Int = x=>y=>x+y;
println(g(3)(2)); def fxx(x:Int)(y:Int) = x+y;
println(fxx(3)(2)); def foo(x:Int) = {
val tmp = (y:Int) => x+y;
tmp;
}
println(foo(3)(2)); def foo1(x:Int) = {
def tmp(y:Int) = x+y;
tmp _;
}
println(foo1(3)(2));
}

  

如果函数只有一个变量,并且这个变量在最末尾,则这个变量的下划线也可以省略

def foo(add:Int=>Int):Int= add(2);
println(foo(2+));//p=>2+p 或 2+_ 或 2+

Scala 高级编程练习的更多相关文章

  1. scala 高级编程

    一.函数式编程 Scala中的函数可以独立存在, 不需要依赖任 何类和对象 def  放在类中就是方法:放在外边就是函数 1.将函数赋值给变量 Scala中的函数是一等公民, 可以独立定义, 独立存在 ...

  2. 9、scala函数式编程-集合操作

    一.集合操作1 1.Scala的集合体系结构 // Scala中的集合体系主要包括:Iterable.Seq.Set.Map.其中Iterable是所有集合trait的根trai.这个结构与Java的 ...

  3. scala 函数式编程之集合操作

    Scala的集合体系结构 // Scala中的集合体系主要包括:Iterable.Seq.Set.Map.其中Iterable是所有集合trait的根trai.这个结构与Java的集合体系非常相似. ...

  4. 02.Scala高级特性:第6节 高阶函数;第7节 隐式转换和隐式参数

    Scala高级特性 1.    课程目标 1.1.   目标一:深入理解高阶函数 1.2.   目标二:深入理解隐式转换 2.    高阶函数 2.1.   概念 Scala混合了面向对象和函数式的特 ...

  5. Learning Spark中文版--第六章--Spark高级编程(2)

    Working on a Per-Partition Basis(基于分区的操作) 以每个分区为基础处理数据使我们可以避免为每个数据项重做配置工作.如打开数据库连接或者创建随机数生成器这样的操作,我们 ...

  6. 读《C#高级编程》第1章问题

    读<C#高级编程>第1章 .Net机构体系笔记 网红的话:爸爸说我将来会是一个牛逼的程序员,因为我有一个梦,虽然脑壳笨但是做事情很能坚持. 本章主要是了解.Net的结构,都是一些概念,并没 ...

  7. MVC高级编程+C#高级编程

    本人今年的目标是学习MVC高级编程和C#高级编程,把自己的基础打的扎实,本文中值是一个开到,定期会在上面记录学习的技术点和心得就,加油吧!!!!!

  8. 《C#高级编程》读书笔记

    <C#高级编程>读书笔记 C#类型的取值范围 名称 CTS类型 说明 范围 sbyte System.SByte 8位有符号的整数 -128~127(−27−27~27−127−1) sh ...

  9. jquery插件开发继承了jQuery高级编程思路

    要说jQuery 最成功的地方,我认为是它的可扩展性吸引了众多开发者为其开发插件,从而建立起了一个生态系统.这好比大公司们争相做平台一样,得平台者得天下.苹果,微软,谷歌等巨头,都有各自的平台及生态圈 ...

随机推荐

  1. LoadRunner使用之变量参数化

    LR性能测试之参数化设置 Q:何为参数化? LR在录制程序运行的过程中,VuGen(脚本生成器) 自动生成了包含录制过程中实际用到的数值的脚本,如果你企图在录制的脚本中使用不同的数值执行脚本的活动(如 ...

  2. javaScript AJAX

    AJAX的实现 var sAjax = function () { var sendMsg = { url: "", sendType: "POST", Con ...

  3. ASP.NET中的文件操作(文件信息,新建,移动,复制,重命名,上传,遍历)(亲测详细)

    做了几天的文件操作,现在来总结一下,错误之处,还望指点!以文件为例,如果对文件夹操作,基本上将File换为Directory即可(例:FileInfo file = new FileInfo(Path ...

  4. sprint2的总结及团队贡献分

    本次sprint做了订餐方法,用户可以通过搜索餐桌号进行点餐,查看已点的东西,也可以删除自己不想要的,当订单进入厨房时,厨房根据订单的顺序先后排列做餐,用户也可以通过扫描餐桌的二维码进行点餐. 148 ...

  5. 修改CMD字符编码

    1.参考网址: 1.1.http://blog.useasp.net/archive/2012/04/24/how_to_use_UTF8_encoding_in_Windows_CMD.aspx 1 ...

  6. md语法之行内代码和代码片

    md语法之行内代码和代码片 比如说要在行内写上一句或者半句代码(代码的意思就是某种脚本语言), 用撇号围起来就可以了. 比如: import pandas as pd 写代码片(单独的一块脚本语言)的 ...

  7. Python学习---除法

    python有两种除法,普通除法 a/b ,不论a,b精度 得到的都是浮点数. 4/2 = 2.0    3/5 = 0.6 floor除法,a//b , 得到一个舍弃小数位的整数结果,所以结果永远是 ...

  8. Android进程绝杀技--forceStop

    一.概述 1.1 引言 话说Android开源系统拥有着App不计其数,百家争鸣,都想在这"大争之世"寻得系统存活的一席之地.然则系统资源有限,如若都割据为王,再强劲的CPU也会忙 ...

  9. npm install报错Error: ENOENT

    E:\projects\ueditor\ueditor1_4_3_3-src>npm installError: ENOENT, stat 'C:\Users\Lucas\AppData\Roa ...

  10. linux笔记:shell编程-文本处理命令

    cut(字段提取命令,也叫列提取命令): printf(格式化输出命令): awk(awk就是把文件逐行的读入,以空格为默认分隔符将每行切片,切开的部分再进行各种分析处理): sed(sed是一个很好 ...