보통 Java 언어에서는 int type 의 변수와 유리수 type 의 변수를 계산하기 위해서는 lvalue 가 유리수 type 이 아니기 때문에, int type 의 변수를 유리수 type 의 wrapper 클래스를 이용하여, boxing 이라는 과정을 거치고 다시 오른쪽 변수인 유리수 type 의 변수를 인자를 갖는 method 를 호출하여 해결 한다.
예를 들어서, Java 언어로 구현된, 유리수 클래스가 있다고 하자.
Rational.java
public class Rational {
public Rational add(Rational rvalue) { ... }
... // 내부 method 들 구현 생략
}
int a = 10;
Ratioan r = new Rational (1, 3) // 분수 1/3 을 의미
Rational result = a.add(r); // 이 문법은 허용이 되지 않는다.
Rational ra = Rational(a); // 정수인 a 를 유리수를 대변하는 클래스의 객체로 형 변환을 한다.
Rational result2 = ra.add(r); // 이렇게 계산을 해야 문제가 없다.
위와 같은 코드는 자연스럽지 못하다. 왜냐하면 기본적으로 Java 언어에서는 Operator Overloading 을 허용하지 않기 때문이다. add 대신에 + 를 사용하면 훨씬 자연스러워 보이지 않을까?
하지만, Scala 는 이런 문제를 해결하기 위해서 좀 더 유연한 방법을 제시한다. Scala 언어에서는 Operator Overloading 을 허용한다. 그리고 묵시적 형변환이라는 기능도 제공한다. 무슨 말인지 자세히 알아보기 위해서, 아래의 코드를 살펴보자. 아래의 코드는 유리수를 나타내는 클래스를 Scala 언어로 구현한 것이다.
/**
유리수를 나타내는 클래스 구현
유리수의 덧셈(+), 뺄셈(-), 곱셈(*),나눗셈(/) 이 구현되어 있다.
유리수의 공통분모를 구하기 위해서 GCD(Great Common Divisor) 최대공약수를 Recursive 함수로 구현하였다.
계산 가능한 수식은 유리수 연산자 유리수, 유리수 연산자 정수 의 형태만 가능하다.
TODO 유리수 연산자 실수 를 지원
*/
// Companion class of Rational singleton object
class Rational(n: Int, d: Int) {
require(d != 0)
private val g = gcd(n.abs, d.abs)
val numer: Int = n / g
val denom: Int = d / g
def this(n: Int) = this(n, 1)
def + (that: Rational): Rational = {
new Rational(numer * that.denom + that.numer * denom, denom * that.denom)
}
def + (that: Int): Rational = {
new Rational(numer + denom * that, denom)
}
def - (that: Rational): Rational = {
new Rational(numer * that.denom - that.numer * denom, denom * that.denom)
}
def - (that: Int): Rational = {
new Rational(numer - denom * that, denom)
}
def * (that: Rational): Rational = new Rational(numer * that.numer, denom * that.denom)
def * (that: Int): Rational = new Rational(numer * that, denom)
def / (that: Rational): Rational = new Rational(numer * that.denom, denom * that.numer)
def / (i: Int): Rational = new Rational(numer, denom * i)
override def toString = numer + "/" + denom
private def gcd(a: Int, b: Int): Int = if (b == 0) a else gcd(b, a % b)
}
// Copanion object of Rational class
object Rational {
/**
Int 클래스에 존재하는 연산자 method 는 rvalue 로 Rational 클래스를 허용하지 않기 때문에,
Int type 의 변수와 Rational type 의 변수 연산을 하기 위해서는 이 method 가 필요하다.
이 Method 는 Int type 의 변수를 필요할 때, Rational type 으로 형 변환을 해준다.
*/
implicit def intToRational(x: Int) = new Rational(x)
def main(args: Array[String]) {
val x = new Rational(16, 42)
val x2 = new Rational(50, 42)
println("16/42 = 8 / 21")
println("50/42 = 25 / 21")
print("\n8/21 + 25/21 = ")
println(x + x2)
print("\n8/21 + 1 = ")
println(x + 1)
print("\n8/21 - 25/21 = ")
println(x - x2)
print("\n8/21 - 2 = ")
println(x - 2)
print("\n8/21 * 25/21 = ")
println(x * x2)
print("\n2 * 8/21 = ")
println((2 * x))
print("\n8/21 / 25/21 = ")
println(x / x2)
print("\n2 / 8/21 = ")
println((2 / x))
println("2 + 4 = " + (2 + 4))
}
}
'Programming > Scala' 카테고리의 다른 글
Set 간단 팁 (0) | 2012.11.27 |
---|---|
Scala - Application (Scala 언어 응용프로그램) (0) | 2011.11.10 |
Scala - Pattern matching example 2 (Scala 언어로 패턴 매칭하기) (0) | 2011.11.10 |
Scala - Creating IntelliJ Scala project using sbt (sbt 를 이용하여 IntelliJ 용 Scala project 생성하기) (0) | 2011.11.10 |
Scala - Basic calculator using Parser Combinator (스칼라 언어로 만드는 간단한 사칙 연산 계산기 프로그램) (0) | 2011.11.10 |