행위

러스트(프로그래밍 언어)

조무위키

imported>왕킹님의 2022년 1월 20일 (목) 20:17 판
(차이) ← 이전 판 | 최신판 (차이) | 다음 판 → (차이)
주의. 이 문서는 공머생들이 좋아하는 주제 혹은 공머생 그 자체에 대해 다룹니다.
본 문서가 다루는 내용에 지나치게 탐닉할 경우 필연적으로 여성들과 멀어지게 됩니다.
이는 조무위키가 책임지지 않습니다.
이 문서는 너무 위백스럽습니다.
이 문서는 출처가 분명하지 않습니다.
이 문서는 칼같이 레퍼런스를 지키고 자기들이 전문적이라 생각하는 위백충들이 다녀갔거나 위백화가 된 문서입니다.
문서 내용이 하도 엄격 진지 근엄해서 노잼이니 가능한 꿀잼 문서로 바꿔주시기 바랍니다.[출처 필요]

개요[편집]

모질라에서 파이어폭스에 쓸려고 만든 프로그래밍 언어다.

안전하면서도 C/C++과 동일한 성능을 갖는 언어이며 고와 더불어 메이저 시스템 프로그래밍 언어로 성장할 가능성이 높은 언어다.

특히 성능 면에서는 C/C++과 동일하거나 더 앞선 결과를 보여줬다.[[1]]

특징[편집]

안전성[편집]

안전성이 가장 큰 특징이며 안전성을 위해 다음과 같은 특징을 가진다.

먼저 변수 선언을 할 때 let이라는 키워드를 쓰는데 이건 불변변수다. 가변변수로 바꾸려면 let mut 다음에 변수명을 써야한다. <source lang="rust"> let x = 42; let mut y = 42; x = 10; // 에러다. y = 10; // 에러가 아니다. </source> 변수가 불변인데 왜 상수가 아니라 변수로 부르냐면 값이 메모리에 저장되기 때문이다. 굳이 이렇게까지 하는 이유는 당연히 안전성 때문인데 let으로만 선언한 x는 불변이므로 이것이 어떻게 변하는지 신경 않쓰고 로직을 짤 수 있다.

두 번째로는 소유권 개념이 있다. 소유권 이동은 타입이 Copy 특성이 없으면 발생한다. 변수는 소유권을 가지며 대입하는 순간 소유권이 이전된다는 것이다. <source lang="rust"> struct A(i32); // Copy 특성이 없는 튜플 구조체

fn main() {

   let x = 100; // 정수형은 Copy 특성이 있음.
   let y = x; // 소유권 이동 없이 복사해서 줌.
   let z = x; // 에러가 아니다. Copy 특성을 가진 타입은 소유권을 절대 안준다.
   let a = A(200); // Copy 특성이 없는 구조체.
   let b = a; // 소유권이 a에서 b로 이동.
   let c = a; // 에러! a는 줄 소유권이 없음.

} </source> 소유권이 이동하는 상황은 대입할 때, 함수에 인자로 넘길 때, 피연산자가 될 때 등등 변수가 이름 그대로 사용되는 모든 상황이다. <source lang="rust"> fn main() {

   let a = String::from("A"); // String타입은 Copy 특성이 없다.
   a; // a의 소유권이 이동한다. 소유권을 받을 변수가 없으니 값의 주인이 없어진다.
   // 이제부터 a는 소유권이 없어 사용 불가.
   let b = String::from("B");
   let x = std::ops::Add::add(b, "2"); // b의 소유권이 add 함수로 넘겨진다.
   // 이제부터 b는 소유권이 없어 사용 불가.
   
   let c = String::from("C");
   let y = c + "3"; // 위와 마찬가지로 c의 소유권이 더하기연산자함수로 넘겨진다.
   // 이제부터 c는 소유권이 없어 사용 불가.

} </source> 소유권 개념을 요약하면

1. 메모리에 있는 값은 주인을 하나만 가진다.

2. 이름으로 표현되는 변수만이 주인이 된다. 주인 없는 값은 버려진다.

3. 주인이 자기 수명인 스코프 { ... } 를 벗어나면 주인은 없어지고 소유한 값은 버려진다.

소유권 개념이 필요한 이유는 당연히 데이터 레이스을 없애기 위해서다. C/C++에서는 동시에 하나의 변수에 접근하려면 락을 걸어야 하는데 이건 성능 저하가 심하고 이것도 실수하면 데이터 레이스가 발생하는데 이건 한 데이터에 변경을 동시에 해서 하나의 변경만 유효한 상황을 만든다.

물론 데이터 레이스를 없애는 극약 처방도 있는데 모든 변수가 상수인 하스켈의 방식이다. 근데 이건 시스템 프로그래밍에서는 효율이 나올 수가 없는 방식이라서 러스트는 소유권 개념을 선택한 것.

그래도 극단적인 소유권 중심의 언어 디자인은 아니다. 변수이름 앞에 &를 이용해서 변수이름을 빌리는 방식이 있으며 &variable 같은 것을 참조자라고 한다. 이걸 함수 인자에 집어넣으면 함수는 참조자를 통해 변수가 소유한 값을 읽을 수 있다. <source lang="rust"> let a = String::from("A"); let len = String::len(&a); // a의 이름을 빌려서 참조자를 len함수에게 준다. a의 소유권은 유지된다. let len = a.len(); // 위와 같은 표현이다. let len = String::len(a); // 소유권을 넘기려 하지만, String::len은 인자로 &self를 받으므로 인자 타입 불일치 에러! </source> 소유권이 필요없는 메서드는 대부분 소유권 대신에 참조자를 매개변수로 받으니 쓸데 없이 프로그래머가 함수에 소유권을 넘길 일을 없다.

성능[편집]

즤! 이 문싀 댓은 좐 빫닏!
넘 빬 울 뉀 뵞 않싇! 넴! 겏라!~~

C/C++과 비슷한 비용 없는 추상화가 기본적으로 깔려있다. 즉 현대적인 기능들을 쓰는데 성능 저하가 발생하는 추상화가 없다는 뜻이다.

예를 들어 위백 러스트 문서에 있는 팩토리얼을 적당히 바꾸면 <source lang="rust"> fn factorial_0(n: u64) -> u64 {

   let mut result = 1;
   for i in 1..=n {
       result *= i;
   }
   result

}

fn factorial_1(n: u64) -> u64 {

   let mut result = 1;
   (1..=n).for_each(|i| result *= i);
   result

} </source> 이렇게 되는데 이 둘은 비슷한 성능을 가지지만 for_each쪽이 훨씬 깔끔하다.

소유권 개념을 채용했기 때문에 가비지 컬렉션이 필요없고 기본적으로 가비지 컬렉션이 없기 때문에 런타임 오버헤드가 일어나지 않는다. 이건 지금 경쟁하고 있는 고언어에 비해서 메모리 효율성이라든지 속도가 더 좋을 수 있는 구조적 특징이다. 그래도 참조 카운터 등을 라이브러리로 지원하니까 완전히 가비지 컬렉션이 없는건 아니고 필요하면 라이브러리에서 쓸 수 있다.

함수형 언어의 기능[편집]

현대 프로그래밍 언어, 특히 함수형 언어에서 많이 도입된 패턴 매치가 들어오고 switch-case문이 나갔다. 이게 왜 중요하냐면 패턴 매치가 switch-case문보다 훨씬 범용적이고 시스템 프로그래밍 언어중에서는 이 기능을 추가한 언어가 별로 없기 때문이다.

map, reduce, filter같은 함슬람 뽕을 느끼게하는 함수들을 사용할 수 있다.

cargo[편집]

그리고 나머지 눈에 띄는 특징으로는 npm과 비슷한 cargo인데 C/C++의 좆같은 라이브러리 의존성을 해결하고 증분 컴파일 비스무리하게 패키지 내의 변화가 없으면 그냥 재컴파일을 안하는 훌륭한 물건이다.