입력은 있으나, 출력은 없고, 외부 환경(전역 변수나 다른 클래스 등..)에 관여함(부수효과)
def join(name:String, age:Int) : Unit = {
println("고락가락닷컴 회원가입 완료")
members += new User(name, age)
memebrCount += 1
}
일반적인 프로그래밍 언어에서 컬렉션을 이용하는 방식 또한 이러한 부수효과에 많이 노출되어 있음
스칼라에서는 foreach가 그러한 것임
var total = 0
val list = List(10, 20, 30, 40)
list.foreach(item => total += item)
total을 구하는 방식, 다음과 같이 할수도 있음
var total = 0
def sum(item: Int) = total += item
list foreach sum // list.foreach(sum) 과 동일
foreach안에서 total이라는 외부 변수를 수정함으로, 위험함.. 이는 다음과 같이 수정 가능
object Ex_9_1 {
def main(args: Array[String]): Unit = {
val list = List(10, 20, 40, 55)
def foreach(list: List[Int]): Int = {
def add(list: List[Int], total: Int): Int = {
list match {
case List() => total
case List(item) => total + item
case head :: tail => add(tail, total + head)
}
}
add(list, 0)
}
println(foreach(list))
}
}
위의 코드는 add 에서
List가 없을때는 total을 반환
List에 아이템이 하나 있을때는 total에 item을 더해서 반환
List에 아이템이 두개 이상 있을때는 head(첫번째 아이템)와 tail(그외 나머지)를 나누어 add(tail, total + head)를 반환
하지만 #7 에서 소개된 .foldLeft를 이용하여, 더 간단히 할 수 있음
object Ex_9_2 {
def main(args: Array[String]): Unit = {
val list = List(10, 20, 40, 55)
val result = list.foldLeft(0)((total, item) => total + item)
println(result)
}
}
catch {
case e: FileNotFoundException => println("No File")
case e: IOException => ex.printStackTrace()
}
사용자 입력
scala.io.StdIn.readLine 을 이용하여 사용자 입력을 받을 수 있음
var a = scala.io.StdIn.readLine
아이더(Either)
둘중의 하나의 자료형을 담을 수 있음
object Ex_9_4 {
def main(args: Array[String]): Unit = {
val input = scala.io.StdIn.readLine("값을 입력하세요 : ")
val result: Either[String, Int] = try {
Right(input.toInt)
}
catch {
case e: Exception => Left(input)
}
println(result.getClass)
println(result.left.getOrElse("is not left"))
println(result.getOrElse("is not right"))
}
}
Either는 Right를 기본값으로 함 (그래서 .getOrElse를 하면 Right를 기준으로 나옴)
.isLeft 와 .isRight로 이 값이 어떤 형태인지 알 수 있음
파일 입출력
import java.io.{File, PrintWriter}
import scala.io.StdIn.readLine
object Ex_9_5 {
def main(args: Array[String]): Unit = {
val fileName = "Ex_9_5_result.txt"
var input = readLine("파일에 쓸 내용을 입력하세요 : ")
val writer = new PrintWriter(new File(fileName))
writer.write(input)
writer.close
}
}
책에서는 scala.io.Source를 임포트 해야 한다는데... 필요 없는데?
접근 제한자
private로 외부로 부터 메서드 접근을 막을 수 있음
java처럼 protected도 사용할 수 있음
범위
private
protected
예약어 없음
동일 클래스 (객체)
O
O
O
상속 클래스
X
O
O
다른 패키지
X
X
O
동반객체에서는 private도 접근 가능
object Ex_9_7 {
object Companion {
private def ma = {}
def mb = {}
}
class Companion {
val a = Companion.ma
val b = Companion.mb
}
def main(args: Array[String]): Unit = {
val c = new Companion
println(c.a)
}
}
변경불가능하게 컬렉션 이용하기
foreach안에서 total이라는 외부 변수를 수정함으로, 위험함.. 이는 다음과 같이 수정 가능
예외 처리
사용자 입력
아이더(Either)
파일 입출력
접근 제한자
동반객체에서는 private도 접근 가능