有没有办法在所有对象之间共享变量(从同一类型实例化)?考虑以下简单程序。两个对象name
和name2
具有相同的类型A
。有没有办法连接两个实例properyList
和name
中的name2
?
class A {
var properyList = List[String]()
def printProperties(): Unit = {
println(properyList)
}
}
object Experiment {
def main(args: Array[String]): Unit = {
val name = new A
val name2 = new A
name.properyList = List("a property")
name.printProperties()
name2.printProperties()
}
}
输出
List(a property)
List()
任何更改类定义的方法,只需更改其中一个对象中的.properyList
,它就会在所有实例中更改?
答案 0 :(得分:9)
你似乎在寻找的是一个类变量。在我开始讨论为什么你应该避免这种情况之前,让我解释一下你可以做什么:
您可以将propertyList附加到随播对象而不是类:
object A {
var properyList = List[String]()
}
class A {
def printProperties(): Unit = {
println(A.properyList)
}
}
现在,为什么你不应该:
虽然 scala 让你做几乎JVM能够做的任何事情,但它的目的是鼓励一种函数式编程风格,它通常避开可变状态,特别是共享,可变状态。即A
中的反模式不仅是propertyList是var
,而不是val
,而是通过伴侣对象共享它,你进一步允许任何人从任何线程更改任何时候所有实例的状态。
将您的数据声明为val
的好处是,您可以放心地传递它,因为您可以确定将来任何时候都无法改变您的身份。
答案 1 :(得分:4)
您似乎在寻找类似java静态字段的内容。
在scala中,你通常可以通过使用伴侣对象来实现类似的东西:
object Main extends App {
class A {
import A._
def printProperties(): Unit = {
println(properyList)
}
}
object A {
private var properyList = List[String]()
def addProperty(prop: String): Unit = {
properyList ::= prop
}
}
val name = new A
val name2 = new A
A.addProperty("a property")
name.printProperties()
name2.printProperties()
}
答案 2 :(得分:2)
如果你想要类似于java的静态字段,你将不得不使用伴侣对象。
Traceback (most recent call last):
File "C:/Python34/Gw2.py", line 6, in <module>
htmlfile = urlopen("http://xiv-market.com/item_details.php?id=2727")
File "C:\Python34\lib\urllib\request.py", line 153, in urlopen
return opener.open(url, data, timeout)
File "C:\Python34\lib\urllib\request.py", line 461, in open
response = meth(req, response)
File "C:\Python34\lib\urllib\request.py", line 574, in http_response
'http', request, response, code, msg, hdrs)
File "C:\Python34\lib\urllib\request.py", line 499, in error
return self._call_chain(*args)
File "C:\Python34\lib\urllib\request.py", line 433, in _call_chain
result = func(*args)
File "C:\Python34\lib\urllib\request.py", line 582, in http_error_default
raise HTTPError(req.full_url, code, msg, hdrs, fp)
urllib.error.HTTPError: HTTP Error 403: Forbidden
代码复制自: "Static" field in Scala companion object
http://daily-scala.blogspot.com/2009/09/companion-object.html
答案 3 :(得分:0)
基于Arne Claassen的回答,但是使用私有的可变集合和伴随对象,这使得它只对伴侣类可见。在scala 2.11.7控制台中尝试了非常简单的示例:
scala> :paste
// Entering paste mode (ctrl-D to finish)
object A {
private val mp = scala.collection.mutable.Map("a"->1)
}
class A {
def addToMap(key:String, value:Int) = { A.mp += (key -> value) }
def getValue(key:String) = A.mp.get(key)
}
// Exiting paste mode, now interpreting.
defined object A
defined class A
// create a class instance, verify it can access private map in object
scala> val a = new A
a: A = A@6fddee1d
scala> a.getValue("a")
res1: Option[Int] = Some(1)
// create another instance and use it to change the map
scala> val b = new A
b: A = A@5e36f335
scala> b.addToMap("b", 2)
res2: scala.collection.mutable.Map[String,Int] = Map(b -> 2, a -> 1)
// verify that we cannot access the map directly
scala> A.mp // this will fail
<console>:12: error: value mp is not a member of object A
A.mp
^
// verify that the previously created instance sees the updated map
scala> a.getValue("b")
res4: Option[Int] = Some(2)