我有一个Set,我想在调用Set时在该Set的末尾隐式添加另一个值。
例如,我需要这样的东西才能工作:
implicit def addToSet(set: Set[Int]) = set + 4
val s = Set(1, 2, 3)
println(s) // Set(1, 2, 3, 4)
用例:
我正在建立一个网站(使用PlayFramework),并且我拥有大约20-30套角色,分别对应于不同的功能。对于每个页面,只有某些角色才能访问某些功能,因此每次我需要检查角色特权(以伪代码:if(role.canAccess(/*name of page*/))
)时,我都有一些功能,该特权检查用户是否按原样登录的角色包含在与/*name of page*/
相对应的集合中。
我现在正在创建一个超级用户,该用户可以访问每个页面上的所有功能,因此用户的“角色”必须位于每个Set中。我不想通过手动将此角色添加到每个Set来执行此操作,因为我希望此角色具有可伸缩性且易于维护,因此我希望找到一种解决方案,将这种新的超级角色自动添加到幕后的每个Set中
只要他们不修改我已经拥有的原始Set,我也可以接受非隐式答案。
答案 0 :(得分:2)
我认为这就是您要寻找的东西
trait Implicits {
implicit class AddIntoSet[T](set: Set[T]) {
def add(t: T): Set[T] = {
set.+(t)
}
}
}
object Solution1 extends App with Implicits {
val s = Set(1, 2, 3)
println(s.add(4)) // Set(1, 2, 3, 4)
}
答案 1 :(得分:1)
就像其他人说的那样,这可能不是一个好主意,但如果确实需要,您可以尝试对自己的Set
对象进行一些修改:
import scala.collection.generic.SetFactory
import scala.collection.{GenSet, Set, immutable}
object CustomSet extends SetFactory[Set]{
def newBuilder[A] = immutable.Set.newBuilder[A]
def apply[T](elems: T*)(implicit extra: T): Set[T] = {
val orig: Set[T] = super.apply(elems).flatten
val withExtra: Set[T] = orig union GenSet(extra)
withExtra
}
}
implicit val extraInt: Int = 4
implicit val extraStr: String = "c"
val myNumNewSet: Set[Int] = CustomSet(1,2,3)
val myStrNewSet: Set[String] = CustomSet("a", "b")
这些将返回:
scala> val myNumNewSet: Set[Int] = CustomSet(1,2,3)
myNumNewSet: scala.collection.Set[Int] = Set(1, 2, 3, 4)
scala> val myStrNewSet: Set[String] = CustomSet("a", "b")
myStrNewSet: scala.collection.Set[String] = Set(a, b, c)
答案 2 :(得分:0)
也许您可以使用类型别名?
object Roles {
type Role = Int //Optionally you can use type tagging to make it more type-safe
type Roles = Set[Role]
val SuperRole = 4
def apply(roles: Role*): Roles = {
Set(SuperRole) ++ roles
}
}
println(Roles(1,2,3)) // Set(4, 1, 2, 3)
println(Roles() ++ Set(5,6)) // you can also use all methods from Set
这还有一个优势,那就是,如果您在角色以外的其他范围内使用它,则不会造成干扰:
val idsOfUsers = Set(10,12,22) // Set(10, 12, 22)
val roles = Roles(10,12,22) //Set(4, 10, 12, 22)