I have the following program:
class Rational(n: Int, d: Int) {
require(d != 0)
private val g = gcd(n.abs, d.abs)
val numer = n / g
val denom = d / g
def this(n: Int) = this(n, 1)
def this(s: String) = {
val regex: Regex = "^([ -]?(\\d |\\d*\\.?\\d )|\\d*\\/?\\d )$".r
if (!regex.matches(s)) throw new NumberFormatException()
val input: Array[String] = s.split("\\.|\\/")
val num: Int = input(0).toInt
if (input.length equals 1)
this(num, 1) // problem here
else
this(num, input(1).toInt) // problem here
}
}
I tried to create the constructor with some logic. However, I cannot due to
'Rational' does not take parameters
What's the problem?
CodePudding user response:
Try to introduce a helper method
import scala.util.matching.Regex
def gcd(i: Int, i1: Int): Int = BigInt(i).gcd(BigInt(i1)).toInt
class Rational(n: Int, d: Int) {
require(d != 0)
private val g = gcd(n.abs, d.abs)
val numer = n / g
val denom = d / g
def this(n: Int) = this(n, 1)
def this(s: String) = {
this(Rational.transformStr(s)._1, Rational.transformStr(s)._2)
}
}
object Rational {
// helper method
def transformStr(s: String): (Int, Int) = {
val regex: Regex = "^([ -]?(\\d |\\d*\\.?\\d )|\\d*\\/?\\d )$".r
if (!regex.matches(s)) throw new NumberFormatException()
val input: Array[String] = s.split("\\.|\\/")
val num: Int = input(0).toInt
if (input.length equals 1)
(num, 1)
else
(num, input(1).toInt)
}
}
or better, factory methods (because constructors have many limitations)
class Rational(n: Int, d: Int) {
require(d != 0)
private val g = gcd(n.abs, d.abs)
val numer = n / g
val denom = d / g
}
object Rational {
// factory methods
def apply(n: Int) = new Rational(n, 1)
def apply(s: String): Rational = {
val regex: Regex = "^([ -]?(\\d |\\d*\\.?\\d )|\\d*\\/?\\d )$".r
if (!regex.matches(s)) throw new NumberFormatException()
val input: Array[String] = s.split("\\.|\\/")
val num: Int = input(0).toInt
if (input.length equals 1)
new Rational(num, 1)
else
new Rational(num, input(1).toInt)
}
}
Executing code in overloaded constructor prior to calling this()
By the way, you can also use default values
class Rational(n: Int, d: Int = 1 /*default*/ ) {
// ...
}
object Rational {
def apply(s: String): Rational = ???
}