Back-end Skill/Kotlin

[Kotlin]코틀린1.8.0에서 새롭게 업데이트 된 기능

Sophie소피 2023. 1. 25. 16:53

CBRT Function

cube root의 단축어로 세제곱근이라는 뜻이다

import kotlin.math.cbrt

val num = 24
val negNum = -num 

println("The cube root of ${num.toDouble()} is: ${cbrt(num.toDouble())}")
println("The cube root of ${negNum.toDouble()} is: ${cbrt(negNum.toDouble())}")

매개변수로 double 과 float를 받아들이고

함수를 가져오고 double 또는 float값을 제공하면 된다.

Eg) ${cbrt(num.toDouble())}") , ${cbrt(negNum.toDouble())}")

@SinceKotlin("1.8")
@WasExperimental(ExperimentalTime::class)
public fun DurationUnit.toTimeUnit(): TimeUnit

@SinceKotlin("1.8")
@WasExperimental(Experimental::class)
public fun TimeUnit.DurationUnit(): DurationUnit

kotlin 시간 패키지의 단위 변환 함수도 안정적이며

toTimeUnit(), DurationUnit()

이 함수는 kotlin과 Java 간의 상호운용성을 개선한다.

import kotlin.time.duration
import kotlin.time.toDuration
import kotlin.time.toDurationUnit

fun wait(timeout: Long, unit: TimeUnit){
	val duration: Duration = timeout.toDuraion(unit.toDurationUnit())
}

Java util 동시시간 단위와 kotlin 시간 기간 간에 쉽게 변환할 수 있다.

getOrElse : 참조할 값이 존재하지 않거나 잘못되었을 경우 지정한 Else 값을 반환받는다.

getOrNull : 참조할 값이 존재하지 않거나 잘못되었을 경우 Null을 반환받는다.

import java.Optional
import koltin.jvm.optionals.getOrDefault 
import koltin.jvm.optionals.getOrElse
import koltin.jvm.optionals.getOrNull

val presentOptional = Optional.of("I'm here")
printlin(presentOptional.getOrNull()) //"I'm here"

val absentOptional = Optional.empty<String>()
println(absentOptional.getOrNull()) //null
println(absentOptional.getOrDefault()) //"Nobody Here"

println(absentOptional.getOrElse{
	println("Optional was absent")
	"Default Value"
})
//"Optional was absent"
//"Default Value"

단위 인스턴스 및 Java optional에 대한 실험적 확장함수는

kotlin1.8에서 선택적 객체와 편리하게 작업하는데 사용할 수 있다.

표준라이브러리에서 안정화된 함수

먼저 비교할 수 있고 뺄 수 있는 시간 표시를 추가했다.

Comparable and Substractable TimeMarks

@Optin(ExperimeatalTime:: class)
fun main timeSource.markNow()
Thread.sleep(500) 
val mark2 = timeSource.markNow()

//Before 1.8 
repeat(4){n
	val elapsed1 = mark.elapsedNow()
	val elapsed2 = mark.elapsedNow()

	println("Measurement ${n + 1}: elapsed1=$elapsed1," +
						"elapsed2$elapsed2, diff=${elapsed1 - elapsed2}")
}

//Measurement 1: elapsed1=504.53957ms, : elapsed2=12.613462ms, diff= 491.926135ms 
//Measurement 2: elapsed1=539.976044ms, : elapsed2=35.469873ms, diff= 504.506171ms 

1.8 이전 버전에서 사용할 경우 @Optin 사용해야한다.

여러 시간 표시와 현재순간 사이의 시간차이를 계산하려면

각 시간 표시에서 한번에 하나 씩 경과된 Now함수만 호출할 수 있었기 때문에

서로 다른 경과된 null함수 호출이 불가능하기 때문에

결과를 비교하기가 어려웠다.

늘 정확히 같은 시간에 실행되므로

여기 내 예에서 두개의 시간 표시가 있음을 알 수 있으며

각각에 대해 경과된 null 함수를 개별적으로 호출한다.

이는 이러한 호출이 다른 시간 순간에 수행됨을 의미한다.

1.8에서 이 문제를 해결하기 위해 경과된 null 함수 호출이

서로 다른 시점에서 이루어지기 때문에

실제로 결과가 일치하지않는 것을 볼 수가 있다.

동일한 시간소스에서 타임마크를 추출한다.

@Optin(ExperimeatalTime:: class)
fun main timeSource.markNow()
Thread.sleep(500) 
val mark2 = timeSource.markNow()

//Since 1.8 
repeat(4){n -> 
	val mark3 = timeSource.markNow() //새로운 타임 마크 인스턴스를 생셩하여 지금 순간을 나타내고 
	val elapsed1 = mark3 - mark1   //다른 타임의 마크를 뺄 수 있다. 
	val elapsed2 = mark3 - mark2

	println("Measurement ${n + 1}: elapsed1=$elapsed1," +
						"elapsed2$elapsed2, diff=${elapsed1 - elapsed2}")
}
println(mark2 > mark1) //prints true

새로운 타임 마크 인스턴스를 생성하여 지금 순간(val mark3 timeSource.markNow())을 나타내고 다른 타임의 마크(elapsed1 , elapsed2)를 뺄 수 있다.

이런 식으로 이러한 계산에서 수집한 결과는 서로 관련이 있고

이제 시간 표시를 비교할 수 있다.

이번 릴리즈에서 한시간 표시가 다른시간보다 늦게 캡쳐되는지 확인할 수 있다.

Extension for java.nio.file.path

Java nio 파일 경로 클래스에 대한 두 가지 새로운 확장 기능을 도입하여

내용에서 디렉토리를 재귀적으로 복사 및 삭제할 수 있다.

복사하려는 콘텐츠와 대상이 있는 소스 디렉토리가 있다.

직관적으로 소스에서 재귀함수에 대한 복사를 호출하고

대상을 매개변수로 제공할 수 있다.

파일 복사가 이것보다 조금 더 복잡할 수 있다는 것을 알기 전에 그러한 코드를 작성했다.

예를 들어 매개변수가 false로 설정된 경우 심폴릭 링크를 처리하는 방법을 지정할 수 있다.

호출은 심볼릭 링크 자체를 복사하지만 대상이 아니지만 매개변수가 참이면

함수는 링크 대상을 재귀적으로 복사합니다.

또한 매개변수가 거짓인 경우 함수가 대상 디렉터리의

기존항목을 덮어써야하는지 여부도 지정할 수 있다.

효과적으로 함수 호출은 디렉터리로 수행됩니다.

누락된 항목만 대상에 추가하여 원본과 대상 간의 병합 작업

파일을 복사하는 동안 예외가 발생하면 어떻게 해야하는지

정의 인스턴스 로그인에 대한 사용자 지정동작을 구현할 수 있는

Lamda식 제공 오류메시지가 표시되면

식은 진행방법을 나타내는 오류결과 인스턴스에서 반환되어야한다.

재정의 매개변수를 제공하지 않으면 항목 복사를 건너뛰거나 프로세스를 종료한다.

실제로 오버로드 버전을 사용하여 항목복사를 위한 사용자 지정작업을 제공할 수 있다.

예를 들어 사용자 지정 논리를 구현할 수 있다.

디렉터리의 파일이름에서 우리가 매개변수로 제공하는 Lamda 표현식은

프로세스를 계속 건너뛰어야하는지 혹은 종료해야하는지를 나타내는 복사 작업결과이다.

@OptIn(ExperimentalPathApi:: class)
fun main() {
	val soruceRoot = path.of(...)
	val destinationRoot = Path.of(...)

	sourceRoot.copyToRecursively(destinationRoot,
		followLinks = false, 	
		onError = { source, target, exception -> 
				println("Failed to copy $source to $target: ${exception.localizedMessage}")
				OnErrorResult.TERMINATE 
}
){ source, target -> 
   if(source.naem.startWith(".")){}
		CopyActionResult.SIP_SUBTREE
} else {
			source.copyToIgnoringExistDirectory(target , 
					followLinks = false)
				CopyActionResult.CONTINUE
	}
}