Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Scala 具有值参数的单例对象?_Scala - Fatal编程技术网

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我正试图建立一个群体理论模型库。我有一个trait
Group[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)
}