Scala 中的好友访问
Friend access in Scala
考虑
包 p1
中定义的函数 f
一个包 p2
不包含 p1
一个包 p3
,它不包含 p2
或 p1
,也不包含在 p2
或 p1
中。
在 Scala 中,是否可以声明 f
可从包 p2
而不是其他包(例如 p3
)访问?
如果我将您的规则扩展到极限,这是可能的。虽然我不确定这是有意为之还是您忘记了规则。
scala> :paste -raw
// Entering paste mode (ctrl-D to finish)
package p1 {
object O { private[p1] def f = println("f") }
package p2 {
object O { def x = p1.O.f }
}
}
// Exiting paste mode, now interpreting.
scala> :paste -raw
// Entering paste mode (ctrl-D to finish)
package p3 {
object O { def x = p1.O.f }
}
// Exiting paste mode, now interpreting.
<pastie>:2: error: method f in object O cannot be accessed in object p1.O
object O { def x = p1.O.f }
^
There were compilation errors!
如果 p2
也不能被 p1
包含,我认为没有办法保证 f
不能从其他地方访问。您可以使用密封的特征和隐含技巧。
package p2 {
object O { def x = p1.O.f }
}
package object p2 {
sealed trait Friend
private[p2] implicit val p2Friend: Friend = new Friend {}
}
package p1 {
object O { def f(implicit friend: p2.Friend) = println("f") }
}
package p3 {
object O { def x = p1.O.f(null) }
}
但现在如您所见,您仍然可以在包 p3
中作弊。如果不作弊 f
无法在 p1
本身中访问,因为 p1
也没有必要的隐式。
您可以在 f
中检查 friend
是否为 null
。那么 p3
并不能真正使用 f
但它只会在运行时失败,而不会在编译时失败。虽然如果有人路过 null
如果事情在运行时爆炸,他们不能真正抱怨。
考虑
包
p1
中定义的函数f
一个包
p2
不包含p1
一个包
p3
,它不包含p2
或p1
,也不包含在p2
或p1
中。
在 Scala 中,是否可以声明 f
可从包 p2
而不是其他包(例如 p3
)访问?
如果我将您的规则扩展到极限,这是可能的。虽然我不确定这是有意为之还是您忘记了规则。
scala> :paste -raw
// Entering paste mode (ctrl-D to finish)
package p1 {
object O { private[p1] def f = println("f") }
package p2 {
object O { def x = p1.O.f }
}
}
// Exiting paste mode, now interpreting.
scala> :paste -raw
// Entering paste mode (ctrl-D to finish)
package p3 {
object O { def x = p1.O.f }
}
// Exiting paste mode, now interpreting.
<pastie>:2: error: method f in object O cannot be accessed in object p1.O
object O { def x = p1.O.f }
^
There were compilation errors!
如果 p2
也不能被 p1
包含,我认为没有办法保证 f
不能从其他地方访问。您可以使用密封的特征和隐含技巧。
package p2 {
object O { def x = p1.O.f }
}
package object p2 {
sealed trait Friend
private[p2] implicit val p2Friend: Friend = new Friend {}
}
package p1 {
object O { def f(implicit friend: p2.Friend) = println("f") }
}
package p3 {
object O { def x = p1.O.f(null) }
}
但现在如您所见,您仍然可以在包 p3
中作弊。如果不作弊 f
无法在 p1
本身中访问,因为 p1
也没有必要的隐式。
您可以在 f
中检查 friend
是否为 null
。那么 p3
并不能真正使用 f
但它只会在运行时失败,而不会在编译时失败。虽然如果有人路过 null
如果事情在运行时爆炸,他们不能真正抱怨。