Scala 具有值参数的单例对象?
我试图为每个自然数创建一个单例对象 对象不能接受参数,所以我尝试使用类。我有一些逻辑来确保每个数字只创建一个对象。以下是我迄今为止所做的工作,正如我所期望的:Scala 具有值参数的单例对象?,scala,Scala,我试图为每个自然数创建一个单例对象 对象不能接受参数,所以我尝试使用类。我有一些逻辑来确保每个数字只创建一个对象。以下是我迄今为止所做的工作,正如我所期望的: class B(val n: Int) object A extends (Int => B) { val map = collection.mutable.Map[Int,B]() def apply(n: Int) : B = { if (!map.contains(n))map.put(n,n
class B(val n: Int)
object A extends (Int => B) {
val map = collection.mutable.Map[Int,B]()
def apply(n: Int) : B = {
if (!map.contains(n))map.put(n,new B(n))
map(n)
}
}
然后,我可以使用A(3)
作为一个单身汉
理想情况下,我只希望A能够创建B对象-例如,我希望禁止在A
范围之外创建B
对象。因此,我尝试将B
作为A
的内部类,如下所示:
object A extends (Int => A.B) {
val map = collection.mutable.Map[Int,B]()
def apply(n: Int) : B = {
if (!map.contains(n))map.put(n,new B(n))
map(n)
}
class B private[A] (val n: Int)
}
但现在我得到了这个错误:
错误:涉及对象A的非法循环引用
用Any
非法地替换A.B
,一切都按我所希望的那样运行
有没有一种很好的方法来做我想做的事情
编辑
Paul Renauld的回答很好地解决了限制范围的问题!谢谢
我现在要求的是对非法循环引用的解释。我尝试了一个快速的谷歌搜索,但似乎找不到好的资源来了解更多关于这个错误的信息。它的具体含义是什么为什么它会出现;在什么情况下
我想这与Scala的解析/解释/编译方式有关——对此我知之甚少。也许我的问题的答案是指向有关Scala编译器的资源或某个参考页的链接?您不需要将B
作为a
的内部类,以使构造函数只能由a
访问。您可以拥有一个只包含a
和B
的包,并将构造函数的范围限制在此包中
另一个解决方案是不使用A
扩展(Int=>A.B)
:
这也很好用
我现在要求的是对非法循环引用的解释
您想实例化A
<代码>A
扩展Int⇒ A.B
。因此,为了访问作为A
继承链一部分的B
,您需要实例化A
<代码>A
扩展Int⇒ A.B
。因此,为了访问作为A
继承链一部分的B
,您需要实例化A
<代码>A扩展Int⇒ A.B
。因此,为了访问作为A
继承链一部分的B
,您需要实例化A
<代码>A扩展Int⇒ A.B
。因此,为了访问作为A
继承链一部分的B
,您需要实例化A
。等等……为什么需要这些对象?也许有不同的方法可以解决您的问题?仅供参考:您可以使用getOrElseUpdate()
@jwvh,而不是if
检查,谢谢您的提示!我的应用功能现在是内联的,它给我带来了巨大的乐趣@KrzysztofAtłasik我正试图建立一个群体理论模型库。我有一个traitGroup[T]
,它扩展了Set[a]
,并支持逆(x:T):T
和id:T
等操作。我将整数组实现为group[Int]
的子类。我现在尝试将二面体群实现为group[D]
的一个子类,其中D
将是表示e或r^3s的类型。因为每个偶数正整数都有一个二面体群,这就是为什么我要寻找带参数的单体。我这样做是为了好玩,为了加深我对Scala语言循环引用的理解,我不知道它背后的确切逻辑,但我的猜测是:对象A的类型试图被创建,但这将Int函数扩展到了A.B,所以要获得函数类型,我们需要访问B的类型,但B是A的内部类,因此,我们需要创造一个第一,我们得到我们的周期。这是有意义的,谢谢!希望Scala能够做到这一点是否合理?在我看来,这种周期性的参照应该能够得到解决。Scala编译器需要如何对此进行更改?我的推理是实例化可以被分解:A
被部分实例化(作为承诺),那么A.B
就有意义了,这就允许A
被完全实例化。尽管我在这里所做的确实是周期性的,但我不认为这是非法的
object A {
val map = collection.mutable.Map[Int,B]()
def apply(n: Int) : B = {
if (!map.contains(n))map.put(n,new B(n))
map(n)
}
class B private[A] (val n: Int)
}