Scala redis4cats库
redis: RedisCommands[IO, String, String]
- 下面scala中的代码行不会在redis中设置任何记录
redis.set("a", "x")
- 尽管通过终端进行设置时有效
127.0.0.1:6379[2]> set a b OK
- 从scala中检索从终端设置的记录也可以工作,这验证了来自scala的redis连接设置正确
我认为这是由于对IO
的api的混淆造成的
您的代码redis.set("a", "x")
返回类型为IO[Unit]
的值
IO
类型的值是稍后将执行的计算的计划。它是";"参照透明";,这意味着它与类似1 + 1
的值相同
这意味着,例如,这两个程序在语义上是等价的:
IO.println("hi") >> IO.println("hi")
val hi = IO.println("hi")
hi >> hi
与使用非IO相比:
println("hi"); println("hi")
val hi = println("hi")
hi; hi
这两个程序不是等价的-println不是引用透明的。
这意味着如果不使用IO
值,就相当于永远不会构造它。
也就是说,方法foo
和bar
是等价的:
def foo = {
redis.set("a", "x")
123
}
def bar = {
123
}
处理您的案例的最佳方法是确保您构建的redis.set
程序从较高的代码段(例如(合并到flatMap
中
// NB: fa >> fb === fa.flatMap(_ => fb)
def setA: IO[Unit] = redis.set("a", "x") >> IO.println("'a' has been set")
如果代码库的其余部分不使用IO
;CCD_ 14";方法来立即执行IO
值所描述的程序。在这种情况下;"不安全";指的是引用完整性不再被保留,这意味着你不能将等式推理应用于代码。
// Import the default IORuntime to execute your `IO` program
import cats.effect.unsafe.implicits._
def doStuff: Unit = {
redis.set("a", "x").unsafeRunSync()
println("done"
}
def doStuffAsync: Future[Unit] =
redis.set("a", "x").unsafeToFuture()
我建议阅读";作为值的程序";cats effect和fs2的作者之一的系列文章,更详细地介绍了库为什么以这种方式构建,以及使用它可以启用哪些功能