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))
}
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.
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.
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)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With