不定长参数
val arr = List(111,222,333,444,555)
def sum(args:Int*):Int = args.foldLeft(0)((sum,v)=>sum+v) // 就是args.sum求和
sum(arr:_*) // res0: Int = 1665
不定长参数的定义(args:Int*)表示args是一个Seq[Int]序列,当调用sum函数时候传递arr参数。
筛选器
判断在arr中是否有>300的值。
def any(args:Int*):Boolean = args.exists(pred=>pred>300)
any(arr:_*) // true
传递不定数量的函数
传递不定数量的函数做为any的参数,仿照上面传递多个Int*的写法,假设传递的函数的类型是(Int=>Boolean),意思是参数是Int,返回值是Boolean,那么传递多个函数的写法如下。
def any(args:(Int=>Boolean)*):Boolean = args.exists(pred=>pred(300))
要知道args是一个Seq序列,那么any是调用的Seq的exists方法,因为args每个元素此时都是一个(Int=>Boolean)类型的函数,那么pred=>pred(300)的意思是说调用每个函数并将300做为参数,pred就是args中的元素哦。整个定义是判断所有args中的函数在代入300后,是否有返回true的,如果有则any就返回true,否则any返回false。测试一下:
def f1:(Int=>Boolean) = one_int => one_int > 300 // 300>300
def f2:(Int=>Boolean) = one_int => one_int < 200 // 300<200
any(f1,f2) // false
显然,上面f1和f2在传入300后都返回false,那么any就返回false。那么如何把pred=>pred(300)中的300变成可自定义的值呢,如下。
返回一个(Int=>Boolean)类型的函数
让any返回一个(Int=>Boolean)类型的函数,这将消除300的问题。
def any(args:(Int=>Boolean)*):(Int=>Boolean) = one_int => args.exists(pred=>pred(one_int))
现在any会返回一个参数类型是Int的函数。继续使用上面定义的f1和f2的定义,测试一下:
val f3 = any(f1,f2) // 筛选出>300或<200的数
f3(300) // false
f3(400) // true
f3(100) // true
any的问题解决了,但是f1和f2中的固定值也要消除的哦。同样的套路:
def f1:(Int=>(Int=>Boolean)) =
one_int=>
item=>item>one_int
def f2:(Int=>(Int=>Boolean)) =
one_int=>
item=>item<one_int
函数f1和f2都返回类型为(Int=>(Int=>Boolean))的函数。测试一下:
val f3 = f1(400) // >400的数
val f4 = f2(300) // <300的数
val f5 = any(f3,f4) // 筛选>400或者<300的数
f5(222) // true
f5(333) // false
f5(444) // true
使用type定义类型
上面的(Int=>(Int=>Boolean))定义确实够长的,那么多括号看着眼花,使用type来简化一下:
type IntFilter = Int=>Boolean
def f1:(Int=>IntFilter) =
one_int=>
item=>item>one_int
再看any的定义
上面得到any的定义为:
def any(args:(Int=>Boolean)*):(Int=>Boolean) = one_int => args.exists(pred=>pred(one_int))
可以发现这个函数只能用于(Int=>Boolean)的类型,摆脱Int类型的限制是需要解决的。使用泛型:
def anyA*):(A=>Boolean) = one_a => args.exists(pred=>pred(one_a))
1
此处的[A]表示类型,在使用上并没有什么不同,完全可以用上面的例子测试。
是时候展示一个小例子了
借用上面f1到f5的定义,筛选arr中所有>400或<300的元素。
val arr = List(111,222,333,444,555)
arr.filter(f5)
啊啊啊,这完全可以用
arr.filter(_>400 || _<300)
阿里云代金券1000元免费领取地址:https://promotion.aliyun.com/ntms/yunparter/invite.html?userCode=2a7uv47d
新老阿里云账户均可领取!可用于购买阿里云服务器ECS、云数据库RDS、虚拟主机、安骑士、DDoS高防IP等100多云计算产品。 代金券自领取之日起,有效期是30天,请及时使用,过30天后还可以重新领取。