[132] rust

Post on 07-Jan-2017

10.591 Views

Category:

Technology

0 Downloads

Preview:

Click to see full reader

TRANSCRIPT

Rust 프로그래밍 언어

서상현 NAVER LABS

목차

1. Rust 소개 2. 메모리 안전성 3. 쓰레드 안전성 4. 성공적?

1. Rust 소개

1.1 Rust 소개

Mozilla Research에서 개발

2012년 0.1 릴리즈

2015년 1.0 릴리즈

1.2 목표

웹 브라우저 개발

요구사항: 성능

요구사항: 보안

1.2 목표

C++처럼: 오버헤드 없는 추상화

C++처럼: GC 없는 메모리 관리

C++과 달리: 메모리 안전성

C++과 달리: 쓰레드 안전성

1.3 성능

fn sum_pos(v: &[i32]) -> i32 {

v.iter()

.filter(|i| **i > 0)

.map(|i| *i)

.sum()

}

1.3 성능

fn sum_pos(v: &[i32]) -> i32 {

let mut sum = 0;

for i in v {

if *i > 0 {

sum += *i;

}

}

sum

}

2. 메모리 안전성

2.1 쉬운 문제

초기화되지 않은 메모리

널 포인터

배열 인덱스

2.2 초기화되지 않은 메모리

사용할 수 없습니다

컴파일러가 검사합니다

2.2 초기화되지 않은 메모리 (C++)

struct Point {

int x;

int y;

};

int main() {

Point p;

cout << p.x << “ ” << p.y << endl;

}

2.2 초기화되지 않은 메모리

struct Point {

x: i32,

y: i32,

}

fn main() {

let p: Point;

println!(“{} {}”, p.x, p.y);

}

error: use of possibly uninitialized variable: ‘p.x’

2.2 초기화되지 않은 메모리

struct Point {

x: i32,

y: i32,

}

fn main() {

let p = Point { x: 1, y: 2 };

println!(“{} {}”, p.x, p.y);

}

2.3 널 포인터

없습니다

T* 대신 Option<&T>

&T와는 다른 타입

Option은 역참조할 수 없음

2.3 널 포인터 (C++)

int main() {

int* p = nullptr;

cout << *p << endl;

}

2.3 널 포인터

fn main() {

let o = Option<&i32> = None;

if let Some(p) = o {

println!(“{}”, *p);

}

}

2.3 널 포인터

fn main() {

let i = 1;

let o = Option<&i32> = Some(&i);

if let Some(p) = o {

println!(“{}”, *p);

}

}

2.4 배열 인덱스

검사합니다

T[N] 대신 [T; N]

T[] 대신 &[T]

&[T]는 (data, len)

&T와는 다른 타입

&T는 인덱스할 수 없음

2.4 배열 인덱스 (C++)

int main() {

int p[3] = {1, 2, 3};

cout << p[3] << endl;

}

2.4 배열 인덱스

fn main() {

let p: [i32; 3] = [1, 2, 3];

println!(“{}”, p[3]);

}

index out of bounds: the len is 3 but the index is 3

2.4 배열 인덱스

fn main() {

let p: &[i32] = &[1, 2, 3];

println!(“{}”, p[3]);

}

index out of bounds: the len is 3 but the index is 3

2.5 어려운 문제

메모리 관리

무효화

2.6 메모리 관리

메모리에는 유일한 소유권이 있습니다

소유권은 메모리를 해제할 권리입니다

소유권은 이름에 속합니다

소유권은 이전할 수 있습니다

2.6 메모리 관리

fn main() {

let s = String::from(“DEVIEW”);

println!(“{}”, s);

}

s의 수명

2.6 메모리 관리

fn main() {

let s = String::from(“DEVIEW”);

let t = s;

println!(“{}”, t);

}

s의 수명

t의 수명 (s에서 이전)

2.6 메모리 관리

참조를 써서 메모리를 빌려 갈 수 있습니다

&T: 읽기 참조 (접근 가능)

&mut T: 쓰기 참조 (접근, 변경 가능)

T: 소유권 (접근, 변경, 해제 가능)

2.6 메모리 관리

fn main() {

let s = String::from(“DEVIEW”);

let t = &s;

println!(“{}”, s, *t);

}

s의 수명

t의 수명 (s의 참조)

2.6 메모리 관리

메모리를 빌려간 참조가 있는 동안은 해제할 수 없습니다

소유권자의 수명이 다하기 전에 갚아야 합니다

2.6 메모리 관리

fn print(it: String) {

println!(“{}”, it);

}

fn main() {

let s = String::from(“DEVIEW”);

let t = &s;

print(s);

}

s의 수명

t의 수명 (s의 참조)

it의 수명

2.6 메모리 관리

error: cannot move out of ‘s’ because it is borrowed

8 print(s);

note: borrow of ‘s’ occurs here

7 let t = &s;

2.6 메모리 관리

fn print(it: &String) {

println!(“{}”, *it);

}

fn main() {

let s = String::from(“DEVIEW”);

print(&s);

println!(“{}”, s);

}

s의 수명

it의 수명 (s의 참조)

2.7 무효화

메모리를 빌려간 참조가 있는 동안은 변경할 수 없습니다

컴파일러가 참조의 수명을 추적합니다

2.7 무효화 (C++)

int main() {

map<string, string> m;

m[“kr”] = “Korea”;

auto item = m.find(“kr”); // m의 내부를 참조

m.clear(); // 변경으로 참조가 무효화

if (item != m.end()) {

cout << item->first << “ = ” << item->second << endl;

}

}

2.7 무효화

fn main() {

let mut m = HashMap::new();

m.insert(“kr”, “Korea”);

let k = “kr”;

let o = m.get(&k);

m.clear();

if let Some(v) = o {

println!(“{} = {}”, k, *v);

}

}

o의 수명 = m의 내부 참조 수명

m의 변경

2.7 무효화

error: cannot borrow ‘m’ as mutable because it is also borrowed

as immutable

8 m.clear();

note: previous borrow of ‘m’ occurs here; the immutable borrow

prevents subsequent moves or mutable borrows of ‘m’ until the

borrow ends

7 let o = m.get(&k);

2.7 무효화

fn get<’a, ’b>(&’a self, k: &’b K) -> Option<&’a V>

get의 반환값은 k가 아니라 self를 참조한다고 선언합니다

다시 쓰이지 않는 선언은 생략할 수 있습니다

fn get<’a>(&’a self, k: &K) -> Option<&’a V>

2.7 무효화

fn main() {

let mut m = HashMap::new();

m.insert(“kr”, “Korea”);

let k = “kr”;

m.get(&k);

m.clear();

}

임시 = m의 내부 참조 수명

m의 변경

3. 쓰레드 안전성

3.1 메모리 안전성과 쓰레드 안전성

다른 참조가 있는데 메모리를 해제하면 버그

다른 참조가 있는데 메모리를 변경하면 버그 (무효화)

(다른 쓰레드에) 다른 참조가 있는데

(동기화 없이) 메모리를 변경하면 버그 (data race)

3.2 잘못 사용할 수 없는 인터페이스

impl<T> Mutex<T> {

fn lock(&self) -> &mut T { ... }

}

여러 쓰레드에서 변경 가능한 데이터

하지만 변경 가능한 참조를 얻으려면 반드시 동기화를 거쳐야 함

내부를 구현할때는 컴파일러 검사를 잠시 중단 (unsafe)

외부에서 사용할때는 컴파일러가 검사

3.2 잘못 사용할 수 없는 인터페이스

impl<T> RwLock<T> {

fn read(&self) -> &T { ... }

fn write(&self) -> &mut T { ... }

}

4. 성공적?

4.1 성공적?

C++ 노멀 모드 (하드 모드가 아닙니다)

경험적으로: C++만큼 빠릅니다

경험적으로: 확실히 덜 죽습니다

누구나 할 수 있는 시스템 프로그래밍

4.2 미래

이번 주에 1.3 릴리즈 (9월 18일)

6주마다 릴리즈

하위호환성

rust-kr.org: 한국 러스트 사용자 그룹

Q&A

Thank You

top related