Scala 如何编写一个接受可选内部函数的方法
我不确定这个模式叫什么,但这可以用scala编写吗?如果可以,我该怎么做Scala 如何编写一个接受可选内部函数的方法,scala,Scala,我不确定这个模式叫什么,但这可以用scala编写吗?如果可以,我该怎么做 val userId = 1 def getUser(userId: Int): User = { CacheLookup.getOrElse(userId) { userDao.get(userId) } } 我猜这将是一个匿名函数作为参数?有一些类似于映射上的函数——用默认值检查可变映射的。不同之处在于它不会更新地图,这似乎是您想要的(事实上,根据我们在这里遇到的问题,许多使用默认值的人想要的) 另一种选
val userId = 1
def getUser(userId: Int): User = {
CacheLookup.getOrElse(userId) {
userDao.get(userId)
}
}
我猜这将是一个匿名函数作为参数?有一些类似于映射上的函数——用默认值检查可变映射的
。不同之处在于它不会更新地图,这似乎是您想要的(事实上,根据我们在这里遇到的问题,许多使用默认值的人想要的)
另一种选择是记忆。您必须在标准库之外找到它,但它的工作原理有点类似,只是您没有显式地执行缓存操作。基本上,您需要编写一个函数userId=>userDao.get(userId)
,然后获得它的一个记忆版本。当您调用memorized version时,它将检查参数是否有缓存版本,如果有,则提供该版本
请注意,缓存存在一些重要问题。您希望/可以无限期增加,还是应该限制?钥匙会在一段时间后过期吗?这种控制很重要,无论您选择什么解决方案,都必须支持它
至于如何实施,可以是这样的:
def memoize[A, B](f: A => B): A => B = {
var map = Map.empty[A, B]
(key: A) => {
if (!map.contains(key)) map += key -> f(key)
map(key)
}
}
val getUser = memoize((userId: Int) => userDao.get(userId))
此记忆功能采用Function1
(即,具有一个参数的函数)和执行缓存的Function1
(在非常基本的意义上,没有我提到的任何控件)。对于包含更多参数的函数,您必须创建不同版本的参数,或者将其设置为元组
然后我们开始使用,在这里我传递一个函数,该函数接受一个用户id
(一个Int
)并返回一个用户
,我们得到了相同的函数,但现在正在进行缓存
这是一个tupling的例子,只是出于好奇:
scala> val mult = memoize(((x: Int, y: Int) => x * y).tupled)
mult: ((Int, Int)) => Int = <function1>
scala> mult(2, 3)
res18: Int = 6
scala> mult(2 -> 3)
res19: Int = 6
scala>val mult=memoize(((x:Int,y:Int)=>x*y).tuple)
mult:((Int,Int))=>Int=
scala>mult(2,3)
res18:Int=6
scala>mult(2->3)
res19:Int=6
第一个调用,mult(2,3)
实际上是Scala的一个奇点。调用接受元组的函数时,如果要传递多个参数,则Scala将自动进行元组分析。在映射上有类似的功能——使用默认值检查可变映射的。不同之处在于它不会更新地图,这似乎是您想要的(事实上,根据我们在这里遇到的问题,许多使用默认值的人想要的)
另一种选择是记忆。您必须在标准库之外找到它,但它的工作原理有点类似,只是您没有显式地执行缓存操作。基本上,您需要编写一个函数userId=>userDao.get(userId)
,然后获得它的一个记忆版本。当您调用memorized version时,它将检查参数是否有缓存版本,如果有,则提供该版本
请注意,缓存存在一些重要问题。您希望/可以无限期增加,还是应该限制?钥匙会在一段时间后过期吗?这种控制很重要,无论您选择什么解决方案,都必须支持它
至于如何实施,可以是这样的:
def memoize[A, B](f: A => B): A => B = {
var map = Map.empty[A, B]
(key: A) => {
if (!map.contains(key)) map += key -> f(key)
map(key)
}
}
val getUser = memoize((userId: Int) => userDao.get(userId))
此记忆功能采用Function1
(即,具有一个参数的函数)和执行缓存的Function1
(在非常基本的意义上,没有我提到的任何控件)。对于包含更多参数的函数,您必须创建不同版本的参数,或者将其设置为元组
然后我们开始使用,在这里我传递一个函数,该函数接受一个用户id
(一个Int
)并返回一个用户
,我们得到了相同的函数,但现在正在进行缓存
这是一个tupling的例子,只是出于好奇:
scala> val mult = memoize(((x: Int, y: Int) => x * y).tupled)
mult: ((Int, Int)) => Int = <function1>
scala> mult(2, 3)
res18: Int = 6
scala> mult(2 -> 3)
res19: Int = 6
scala>val mult=memoize(((x:Int,y:Int)=>x*y).tuple)
mult:((Int,Int))=>Int=
scala>mult(2,3)
res18:Int=6
scala>mult(2->3)
res19:Int=6
第一个调用,mult(2,3)
实际上是Scala的一个奇点。调用接受元组的函数时,如果要传递多个参数,则Scala将自动进行元组分析。在映射上有类似的功能——使用默认值检查可变映射的。不同之处在于它不会更新地图,这似乎是您想要的(事实上,根据我们在这里遇到的问题,许多使用默认值的人想要的)
另一种选择是记忆。您必须在标准库之外找到它,但它的工作原理有点类似,只是您没有显式地执行缓存操作。基本上,您需要编写一个函数userId=>userDao.get(userId)
,然后获得它的一个记忆版本。当您调用memorized version时,它将检查参数是否有缓存版本,如果有,则提供该版本
请注意,缓存存在一些重要问题。您希望/可以无限期增加,还是应该限制?钥匙会在一段时间后过期吗?这种控制很重要,无论您选择什么解决方案,都必须支持它
至于如何实施,可以是这样的:
def memoize[A, B](f: A => B): A => B = {
var map = Map.empty[A, B]
(key: A) => {
if (!map.contains(key)) map += key -> f(key)
map(key)
}
}
val getUser = memoize((userId: Int) => userDao.get(userId))
此记忆功能采用Function1
(即,具有一个参数的函数)和执行缓存的Function1
(在非常基本的意义上,没有我提到的任何控件)。对于包含更多参数的函数,您必须创建不同版本的参数,或者将其设置为元组
然后我们开始使用,在这里我传递一个函数,该函数接受一个用户id
(一个Int
)并返回一个用户
,我们得到了相同的函数,但现在正在进行缓存
这是一个tupling的例子,只是出于好奇:
scala> val mult = memoize(((x: Int, y: Int) => x * y).tupled)
mult: ((Int, Int)) => Int = <function1>
scala> mult(2, 3)
res18: Int = 6
scala> mult(2 -> 3)
res19: Int = 6
scala>val mult=memoize(((x:Int,y:Int)=>x*y).tuple)
mult:((Int,Int))=>Int=
scala>mult(2,3)
res18:Int=6
scala>mult(2->3)
res19:Int=6
第一个调用,mult(2,3)
实际上是一个Sca