将隐式方法/字段引入匿名函数

时间:2015-03-10 18:14:35

标签: scala implicit

我刚开始使用Scala而且我一直试图创建一个特定的对象。

我有一个对象IdentifierFactory,我想用它来生成Identifier个实例。我这样定义了它:

object IdentifierFactory {
    def apply(f: => Any):Identifier = {
        f; validate

        Identifier(...)
    }

    def validate:Unit = ???
}

我希望能够以下列方式使用它:

IdentifierFactory {
    setName("name");
    addResource(resource);
}

如何声明我可以访问的setNameaddResource(或var},以便它们仅在匿名函数中可见?

1 个答案:

答案 0 :(得分:2)

您可以将构建器传递给匿名函数:

IdentifierFactory { b =>
    b.setName("name")
    b.addResource(null)
}

object IdentifierFactory {
    trait Builder {
       def setName(name: String)
       def addResource(r: Any)
    }

    case class Identifier(name: String, rs: List[Any])

    def apply(f: Builder => Any):Identifier = {
        var nm = "default"
        var rs = List[Any]()
        f(new Builder {
           def setName(name: String) = nm = name 
           def addResource(r: Any) = rs ::= r
        })
        validate

        Identifier(nm, rs)
    }

    def validate: Unit = {}
}

scala> IdentifierFactory { b =>
 |         b.setName("name")
 |         b.addResource(null)
 |     }
res4: IdentifierFactory.Identifier = Identifier(name,List(null))

顺便说一句,您仍然可以通过将名称和资源列表传递给具有默认值的函数来执行相同的操作:

object IdentifierFactory {
    case class Identifier(name: String, rs: List[Any])

    def apply(nm: String = "default", rs: List[Any] = List[Any]()): Identifier = {          
        //validate it right here    
        Identifier(nm, rs)
    }

}

scala> IdentifierFactory()
res7: IdentifierFactory.Identifier = Identifier(default,List())

scala> IdentifierFactory(rs = List(null))
res8: IdentifierFactory.Identifier = Identifier(default,List(null))

scala> IdentifierFactory("nm", List(null))
res9: IdentifierFactory.Identifier = Identifier(nm,List(null))

scala> IdentifierFactory("nm")
res10: IdentifierFactory.Identifier = Identifier(nm,List())

我还建议您返回OptionEither而不是验证例外。