관리 메뉴

밤 늦게까지 여는 카페

[rust 공식 문서 14일 공부] 9일차 본문

For Fun

[rust 공식 문서 14일 공부] 9일차

Jㅐ둥이 2024. 12. 20. 02:58
반응형

10. Generic Types, Traits, and Lifetimes

프로그래밍 언어에는 '중복'을 최소화하기 위해서 여러 기능들이 있습니다.

rust에는 generic, trait, lifetime 기능들이 있다는데 한번 공부해보도록 하겠습니다!

 

10.1. Generic Data Types

rust의 generic 타입은 함수 입력값의 타입만 다르고 동작은 동일할 때 유용하게 사용됩니다.

  • 심지어 성능 저하도 발생하지 않습니다!

 

다음과 같이 i32, char에 대해서 따로 정의한 largest 함수를 하나로 합칠 수 있습니다!

generic 타입 없이 구현했을 때
generic 타입 이용으로 한번에!

 

여기서 눈여겨 볼 것은 T: std::cmp::PartialOrd 입니다.

 

이것이 바로 trait인데 >, < 연산이 가능한 타입들에 대해서만 위의 함수를 사용 가능하다는 뜻입니다.

 

generic은 함수 뿐만 아니라 struct, 메소드에도 사용 가능한데 여기부터는 단순 예시를 보는 것보다 직접 경험해보고 싶네요...!

 

10.2. Traits: Defining Shared Behavior

trait은 다른 프로그래밍 언어들의 interface와 비슷합니다. trait을 사용하면 타입에 메소드 구현을 강제할 수 있는 것이죠.

 

trait에 정의된 메소드를 구현하지 않으면 다음과 같이 컴파일 에러가 발생합니다.

summarize 메소드를 구현하지 않아서 발생한 컴파일 에러

 

모든 메소드를 구현해야 컴파일에 성공하죠!

컴파일 성공

 

trait의 메소드의 기본 동작도 정의할 수 있습니다!

  • golang은 이런 거 없었는데 비교되네요 ㅋㅋㅋ

trait의 메소드 기본 동작 정의

 

trait이 interface와 비슷하다고 말씀드렸는데 다른 점을 보여드리겠습니다.

 

일반적으로 interface 타입을 상속받으면 모든 메소드가 상속받은 interface의 영향을 받게 됩니다.

 

하지만 rust는 선택적으로 trait을 적용할 수 있더라고요.

Display, PartialOrd trait이 있는 타입만 cmp_display 메소드를 사용할 수 있습니다!

 

10.3. Validating References with Lifetimes

lifetime은 값이 원하는 순간까지 유효하다는 것을 보장하기 위해 사용되는 기능입니다.

 

다음 코드를 컴파일 하면 lifetime ~~~ 컴파일 에러가 발생합니다.

어떤 값이 반환될지 몰라서 발생하는 컴파일 에러

 

borrow 한 값이 반환될 수 있는데 어떤 값이 반환되는지 알 수 없기 때문에 발생하는 컴파일 에러입니다.

그러면 어떻게 해야 컴파일 에러를 해결할 수 있을까요?

 

컴파일 에러 메시지에도 나와 있듯이 generic lifetime 라고도 하는 lifetime 어노테이션을 사용하면 됩니다.

  • lifetime 어노테이션을 사용한다고 해서 reference의 유효성이 바뀌는 것은 아니지만 컴파일러가 판단할 수 있게 됩니다.

 

위의 예시를 다음과 같이 함수 정의에 lifetime을 추가하면 컴파일 에러가 발생하지 않습니다.

함수 정의에 lifetime을 추가한 예시

 

이는 longest 함수에서 'a라는 lifetime을 정의했고, x, y 그리고 반환값 모두 lifetime은 'a로 동일해야 한다는 뜻입니다.

 

그래서 main 함수를 다음과 같이 수정하면 string1과 string2의 lifetime이 다르다는 컴파일 에러가 발생하게 됩니다.

lifetime이 유효하지 않아서 컴파일 실패

 

오호 그렇다면 파라미터 y에 정의된 lifetime을 지우면 해결될까요?

그렇지 않습니다. y가 반환되는데 y의 lifetime이 정의되어 있지 않기 때문에 컴파일 에러가 발생하게 됩니다...

컴파일 에러!

 

그렇다면! x, y가 아닌 함수 내에서 정의된 &str을 반환하면 어떨까요?

x와 result의 lifetime이 다르기 때문에 어김없이 컴파일 에러가 발생하게 됩니다!

어김없이 컴파일 에러!

 

rust 컴파일러가 정말 꼼꼼하게 챙겨주네요!

struct에도 reference 타입의 필드들이 있다면 lifetime을 추가해야 합니다. 컴파일러가 struct도 꼼꼼하게 챙겨주겠네요.

 

 

+++ rust 컴파이러의 값 lifetime 추정 방법

1. 각각의 파라미터는 lifetime을 하나씩 갖는다.

2. 만약 파라미터가 하나만 존재한다면 모든 반환값은 해당 파라미터의 lifetime을 갖는다.

3. 만약 메소드에 파라미터가 여러 개 존재한다면 모든 반환값은 struct의 lifetime을 갖는다.

 

largest 예시는 2, 3에도 속하지 않아서 lifetime을 찾을 수 없다는 컴파일 에러가 발생한 것이죠!

 

'static lifetime을 이용해서 프로그램이 실행되는 동안 계속해서 살아 있게되는 변수도 만들 수 있습니다.

반응형