将隐式 def 转换为给定语法的 scala 3

Posted

技术标签:

【中文标题】将隐式 def 转换为给定语法的 scala 3【英文标题】:Convert implicit def to scala 3 given syntax 【发布时间】:2022-01-16 16:18:27 【问题描述】:

对于以下使用猫效果的随机 UUID 生成器:

import java.util.UUID
import cats.effect.Sync
import cats.ApplicativeThrow

trait UuidGen[F[_]]:
  def make: F[UUID]
  def read(string: String): F[UUID]

object UuidGen:
  def apply[F[_]: UuidGen]: UuidGen[F] = implicitly

  implicit def forSync[F[_]: Sync]: UuidGen[F] =
    new UuidGen[F]:
      def make: F[UUID] = 
        Sync[F].delay(UUID.randomUUID)
      def read(string: String): F[UUID] =
        ApplicativeThrow[F].catchNonFatal(UUID.fromString(string))

scala 3 given 语法中 implicit def 的等价物是什么?

【问题讨论】:

你自己尝试过什么?遇到错误? 官方文档应该可以帮助您直截了当:docs.scala-lang.org/scala3/reference/contextual/givens.html 类似:given RandomUuid[F](using F: Sync[F]) with 和下一行 def make: F[UUID] = F.delay(UUID.randomUUID) 谢谢。我已经发布了我的实现作为答案。不幸的是,scala-lang.org 昨天下线了。 github.com/scala/scala-lang/issues/1309 【参考方案1】:
import java.util.UUID
import cats.effect.Sync
import cats.ApplicativeThrow

trait UuidGen[F[_]]:
  def make: F[UUID]
  def read(string: String): F[UUID]

object UuidGen:
  def apply[F[_]: UuidGen]: UuidGen[F] = summon

  given [F[_]: Sync]: UuidGen[F] with
    def make: F[UUID] =
      Sync[F].delay(UUID.randomUUID)
    def read(string: String): F[UUID] =
      ApplicativeThrow[F].catchNonFatal(UUID.fromString(string))

【讨论】:

上下文语法应该被弃用。 @LuisMiguelMejíaSuárez 我不明白您的评论,您能否更具体地指出,究竟应该弃用什么? @AndreyTyukin F[_]: Sync 语法,我个人认为从 Scala 3 开始更好地使用像 (using Sync[F]) 这样的匿名用法 - 但同样,这只是一个个人意见;这就是为什么“应该”

以上是关于将隐式 def 转换为给定语法的 scala 3的主要内容,如果未能解决你的问题,请参考以下文章

如何将隐式参数传递给隐式类

2021年大数据常用语言Scala(三十八):scala高级用法 隐式转换和隐式参数

15Scala隐式转换和隐式参数

我可以将隐式初始化重载为 0 吗?

Python:将对象隐式转换为str?

Scala中的隐式转换|理解