Scala中的模糊概念

模糊概念列表

先记录,后续学完再重点攻破

  • 方法和函数
  • 协变和逆变
  • lambda到底是啥
  • trait和interface的区别
  • currying(柯里化)
  • 提取器对象
  • 隐式转换和隐式参数
  • case定义的类与普通类的区别
  • 传名参数和传值参数
  • 偏函数

方法和函数

参考文章:Scala中方法和函数的区别

  • 定义方式不一样:def定义的叫方法,函数用val/var定义
def m(x: Int) = 2*x
val f = (x: Int) => x*2
  • 无参形式不一样:方法可以没有参数列表,但函数必须有
//方法
def a = 23

//函数
val b=  => 23
  • 调用方式不一样:方法名代表方法调用,函数名只代表函数本身
scala> def m  = 23
m: Int

//可以在命令行中将m作为最终表达式执行,但实际执行的是函数调用
scala> m
res7: Int = 23

scala> def m1(x: Int) = x*2
m1: (x: Int)Int

//不可以将m1作为最终表达式执行,因为有参数
scala> m1
<console>:13: error: missing argument list for method m1
Unapplied methods are only converted to functions when a function type is expected.
You can make this conversion explicit by writing `m1 _` or `m1(_)` instead of `m1`.
       m1
       ^
//执行的时候加括号和参数

scala> m1(3)
res11: Int = 6

scala> def f = ()=>24
f: () => Int

//无参的形式,也必须有参数列表(),可以使用f作为最终表达式执行,但执行结果是一个该函数的结构描述
scala> f
res10: () => Int = $$Lambda$1107/814300680@2e86807a
//执行必须加括号

scala> f()
res12: Int = 24

scala> def f1 = (x: Int) => 2 * x
f1: Int => Int

//有参的函数,也可以使用函数名(f1)作为最终表达式


scala> f1
res13: Int => Int = $$Lambda$1108/1842571958@50a13c2f

//执行的时候,加括号和参数

scala> f1(2)
res15: Int = 4
  • 方法自动转换为函数(ETA expansion):困扰我们的地方是有的需要传函数的地方,也可以传方法,所以我们才会疑惑
  • 方法可以强制转换为函数: 方法后面加_,记得中间有个空格哦。
scala> def m4(x: Int) = 3*x
m4: (x: Int)Int
scala> val f5 = m4 _
f5: Int => Int = $$Lambda$1138/1175368310@4ffe3d42
  • 传名参数:无参的的方法

协变和逆变

参考文章:型变的理解,逆变与协变
scala 学习: 逆变和协变

+A:协变
-A:逆变

简单来说,假如Person[+A],那么如果你定义了2个Person

val person1 = new Person[A1]
val person2 = new Person[A2]

如果A1是A2的子类型,那么person1也是person的子类型,协变正相反。

函数的参数是逆变的,函数的返回是协变的。

lambda

参考文章:Lambda 表达式有何用处?如何使用?
深入理解Lambda
Java 8 Lambda表达式探险

一个无名函数,带=>

trait和interface

先来说说Java中的interface特征,我们可以在接口中定义如下信息:

  • 关键字:interface
  • 属性定义:但必须是final static标识的,也就是不可变,类属性,默认不需要添加final static,自动添加
  • 被继承标识:其他类继承接口需要用implements关键字
  • 方法定义:接口中只能有抽象方法,默认是abstract关键字修饰

  • 继承其他接口:用extends继承,多个用逗号隔开。

接下来我们再来对比下trait看看:

  • 关键字:trait
  • 属性定义:必须初始化,无所谓用valvar
  • 方法定义:抽象方法和有实现的方法也可以。
  • 被继承: extends,多个情况下用with关键字链接。
  • 继承多个特质:extends,多个用with链接。

整体来说,traitinterface强大点,可以定义实现的方法,也可以定义可变的属性

curry

柯里化,一个test(a:Int,b:Int)变成了test(a:Int)(b:Int)就是currytest(2)返回的是一个函数。

提取器对象

含有unapply方法的对象,unapplyapply的操作相反,apply将传入的参数组装成对象,unapply将对象反解析成传入的参数。

case定义的类

会自动生成如下方法:

  • apply
  • unapply
  • getter
  • toString
  • hashCode
  • equals
  • copy

偏函数

map中用case来定义的匿名函数。

隐式转换和隐式参数

Scala之隐式转换

隐式转换的作用,是当某个类缺少某个方法,你无法直接修改源码的情况下,你可以用这个功能去扩展方法。

隐式转换可以理解使用implicit标识的一个方法,方法参数就一个,表示针对某个对象的隐式转换,方法的类型类似(e:T)=>A,类似将T隐式转换为A。2.10后,scala使用implicit定义类来达到隐式转换。

隐式参数,指在方法中,某个参数用implicit定义的,特别是在curry的方法中,特别有用,你可以不用给这个implicit定义的参数赋值,他会去找默认定义的值填上,当然你也可以显式赋值。如果参数类型是匿名函数,那这个隐式参数也是隐式转换。

call-by name/call-by value

Scala基础应用(10)- 传值与传名参数

传值调用(()=>Unit),先计算值,再调用,调用必须加()。传名调用(=>Unit),只在第一次调用的时候才计算,调用只需要用参数名就行。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值