加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

scala – 在DSL中隐藏和确定隐式变量创建

发布时间:2020-12-16 18:30:39 所属栏目:安全 来源:网络整理
导读:在开发DSL时,限制隐式变量范围的最简洁方法是什么,同时隐藏这样一个隐式变量定义的事实? 举个例子,这是理想的行为…… object External{ def funNeedingValue(implicit a : String) { println(a) }}object Main extends App{ useValue("Hi") { // Implicit
在开发DSL时,限制隐式变量范围的最简洁方法是什么,同时隐藏这样一个隐式变量定义的事实?

举个例子,这是理想的行为……

object External
{
    def funNeedingValue(implicit a : String)
    {
        println(a)
    }
}

object Main extends App
{
    useValue("Hi") {
        // Implicit string "Hi" is only defined in this block
        External.funNeedingValue // Prints "Hi"
    }

    External.funNeedingValue // Compilation error: No implicit String defined
}

以下是关闭,但没有所有所需的属性……

// The following works,but does not hide the fact that there is an implicit  
// variable defined.

object Main extends App
{
    {
        implicit val implicitValue = "Hi"
        External.funNeedingValue // Prints "Hi"
    }

    External.funNeedingValue // Compilation error: No implicit String defined
}

// The following hides that there is an implicit variable defined,but breaks
// the scoping requirement and destroys thread safety.

abstract class Parent
{
    implicit var implicitValue = ""

    def useValue(valueToMakeImplicit : String)(f : => Unit)
    {
        implicitValue = valueToMakeImplicit
        f()
    }
}

class Child extends Parent
{
    def go()
    {
        useValue("Hi") {
            External.funNeedingValue // Prints "Hi"
        }

        External.funNeedingValue // Scoping issue: also prints "Hi"
    }
}

object Main extends App
{
    new Child().go()
}

// The following works,but is harder to read and still doesn't really
// hide the implicit value

object Main extends App
{
    def useValue(valueToMakeImplicit : String)(f : String => Unit)
    {
        f(valueToMakeImplicit)
    }

    useValue("Hi") { 
        implicit value : String => {
            External.funNeedingValue // Prints "Hi"
        }
    }

    External.funNeedingValue // Compilation error: No implicit String defined
}

解决方法

你可以制作一个转换的宏

useValue("Hi") {
    // Implicit string "Hi" is only defined in this block
    External.funNeedingValue // Prints "Hi"
}

{
  implicit val iString: String = "Hi"
  External.funNeedingValue
}

我认为没有比没有宏的最后一个例子更好的做法.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读