如何调用辅助构造函数中的方法?

发布于 2024-10-17 12:36:30 字数 551 浏览 2 评论 0原文

class foo(val x:Int){
  def convertToInt(z:string) = {do somthing to convert a string to an integer}
  def this(y:string) = this(convertToInt(y))
}

在辅助构造函数(this(y:string))中调用convertToInt会导致此错误:

error: not found: value convertToInt

我知道我可以使用单例对象并将所有静态函数(如convertToInt)打包到其中,但这是一个好的解决方案吗?

object foo{
    def convertToInt(z:string) = {do somthing to convert a string to an integer}
}   
class foo(val x:Int){
    def this(y:string) = this(foo.convertToInt(y))
}
class foo(val x:Int){
  def convertToInt(z:string) = {do somthing to convert a string to an integer}
  def this(y:string) = this(convertToInt(y))
}

calling convertToInt in auxiliary constructor (this(y:string)) causes this error:

error: not found: value convertToInt

I know I can use a singleton object and pack all static functions like convertToInt into it, but is it a good solution?

object foo{
    def convertToInt(z:string) = {do somthing to convert a string to an integer}
}   
class foo(val x:Int){
    def this(y:string) = this(foo.convertToInt(y))
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

撑一把青伞 2024-10-24 12:36:30

我认为在这种情况下最好的解决方案是使用工厂方法而不是公共构造函数。

因此,您可以定义构造函数 private 并在伴生对象中提供工厂 apply 方法:

class Foo private (val x:Int) 

object Foo {
    def apply(i: Int) = new Foo(i)
    def apply(s: String) = new Foo(convertToInt(s))

    def convertToInt(s: String) = s.toInt
}   

println(Foo(512).x)
println(Foo("256").x)

您可以在此处找到有关构造函数与工厂方法的更多信息:

< a href="https://stackoverflow.com/questions/628950/constructors-vs-factory-methods">构造函数与工厂方法

对于 Scala 来说是一样的。

更新

作为替代解决方案的示例,我制作了非常通用解决方案。 Foo 类现在可以与任何曾经存在或将来可以创建的类<​​/strong>一起使用,假设该类型可以转换(您可以定义它应该如何转换)到/来自 Int:(

trait Convertable[From, To] {
    def convert(from: From): To
}

object Convertable {
    implicit val intString = new Convertable[Int, String] {
        def convert(from: Int) = from toString // your logic here
    }
    
    implicit val stringInt = new Convertable[String, Int] {
        def convert(from: String) = from toInt // your logic here
    }

    implicit def self[T] = new Convertable[T, T] {
        def convert(from: T) = from
    }
}

case class Foo[T](original: T)(implicit toInt: Convertable[T, Int], fromInt: Convertable[Int, T]) {
    val x: Int = toInt convert original
    def toOriginal = fromInt convert x
}


println(Foo(512) x)
println(Foo("256") x)

我可以通过返回 = origin 来定义 toOriginal,但这太无聊了:)

正如你所看到的,这个解决方案是通用的并且更复杂。但据我所知,许多应用程序需要在不同的原始值和/或类之间进行某种转换。因此,在许多情况下,它对于许多情况来说都是合适的(并且可能被认为是非常好的)解决方案,并且可能也适合您。但通常不可能说出所有可能情况的“最佳”解决方案。

I think in this case the best solution would be to use factory methods instead of public constructor.

So you can define your constructor private and provide factory apply methods in companion object:

class Foo private (val x:Int) 

object Foo {
    def apply(i: Int) = new Foo(i)
    def apply(s: String) = new Foo(convertToInt(s))

    def convertToInt(s: String) = s.toInt
}   

println(Foo(512).x)
println(Foo("256").x)

You can find more information about constructor vs factory method here:

Constructors vs Factory Methods

It's the same for Scala.

Update

As an example of alternative solution I made very generic solution. Foo class can now work with any class that ever existed or can be created in future, assuming, that this type can be converted (you can define how it should be converted) to/from Int:

trait Convertable[From, To] {
    def convert(from: From): To
}

object Convertable {
    implicit val intString = new Convertable[Int, String] {
        def convert(from: Int) = from toString // your logic here
    }
    
    implicit val stringInt = new Convertable[String, Int] {
        def convert(from: String) = from toInt // your logic here
    }

    implicit def self[T] = new Convertable[T, T] {
        def convert(from: T) = from
    }
}

case class Foo[T](original: T)(implicit toInt: Convertable[T, Int], fromInt: Convertable[Int, T]) {
    val x: Int = toInt convert original
    def toOriginal = fromInt convert x
}


println(Foo(512) x)
println(Foo("256") x)

(I could define toOriginal by just returning = original, but it would be too boring :)

As you can see, this solution is generic and more complicated. But as far as I saw, many application need some kind of conversion between different primitive values and/or classes. So in many cases it's sutable (and may be event considered very good) solution for many cases and may be for your also. But it's often impossible to tell what's "the best" solution for all possible cases.

半枫 2024-10-24 12:36:30

通过使用角度关于工厂方法的报价而不是辅助构造函数:

class Foo(val s:String) {
      val s = ""
      def bar2:String = s+s
      def bar3:List[Char] = s.toList
}

object Foo extends{
      def bar1(y:List[Char]):String =y.mkString
      def apply(s:String)= new Foo(s)
      def apply(y:List[Char])= new Foo(bar1(y))
}

客户端代码:

val foo1 = Foo(List('a','b'))
println(foo1.s)
println(foo1.bar2)
println(foo1.bar3)

by using angle's offer about factory method instead of Auxiliary Constructor:

class Foo(val s:String) {
      val s = ""
      def bar2:String = s+s
      def bar3:List[Char] = s.toList
}

object Foo extends{
      def bar1(y:List[Char]):String =y.mkString
      def apply(s:String)= new Foo(s)
      def apply(y:List[Char])= new Foo(bar1(y))
}

client code:

val foo1 = Foo(List('a','b'))
println(foo1.s)
println(foo1.bar2)
println(foo1.bar3)
情痴 2024-10-24 12:36:30

你的解决方案并没有那么糟糕。毕竟,convertToInt类似于Java中的静态方法。就我个人而言,我不喜欢辅助构造函数,所以我通常也更喜欢 Easy Angels 解决方案。但是,如果您计划稍后从您的类继承,伴生对象方法将不会针对派生类进行“扩展”,您将必须重新实现该方法。在这种情况下,您应该坚持您的解决方案。

理论上,您可以将该方法放入一个单独的特征中并对其进行扩展,但我不建议这样做。使用继承应仅限于存在真正依赖关系的情况,而不仅仅是为了“方便”。

Your solution isn't that bad. After all, convertToInt is similar to a static method in Java. Personally I don't like auxiliary constructors, so I'd normally prefer Easy Angels solution as well. However if you plan to inherit from your class later, the companion object approach won't "scale" for the derived class, you would have to reimplement that method. In that case you should stick with your solution.

Theoretically you could put that method in a separate trait and extend it, but I wouldn't recommend this. Using inheritance should be limited to cases when there is a real dependency, not just for "convenience".

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文