2017-09-17 4 views
1

다음 C# 코드는 잘 컴파일 : 나는 녹 비슷한 코드를 작성하는 경우가로 변경할 수 불변 v을 빌릴 수 없기 때문에변수가 변경 가능하다는 것을 Rust가 어떻게 알 수 있습니까?

static readonly List<int> list = new List<int>(); 
static void Main(string[] args) 
{ 
    list.Add(1); 
    list.Add(2); 
    list.Add(3); 
} 

, 그것은 컴파일되지 않습니다 :

let v = Vec::new(); 
v.push(1); 
v.push(2); 
v.push(3); 

어떻게 push 기능을 수행 v이 불변이라는 것을 아십니까?

답변

8

모든 변수는 이며 기본값은입니다. 당신은 explicitly tell the compiler which variables are mutablemut 키워드 비록해야합니다

let mut v = Vec::new(); 
v.push(1); 
v.push(2); 
v.push(3); 

Vec::push는 벡터에 변경 가능한 참조 (&mut self) 필요로 정의된다

fn push(&mut self, value: T) 

method syntax를 사용을하지만 개념적으로 동일합니다

fn push(&mut Vec<T>, value: T) 

I 을 권장하며 The Rust Programming Language, second edition을 읽습니다. 이 초급 질문뿐만 아니라 당신이 가질 많은 초급 질문을 다룹니다.

3

녹에서는 기본적으로 바인딩을 변경할 수 없습니다. 당신이 밖으로 발견이 매우 그렇지 않다,

List<int> list = new List<int>(); // C# 
let mut list = Vec::new();  // Rust 

그러나 :

readonly List<int> list = new List<int>(); // C# 
let list = Vec::new();      // Rust 

그리고 이들을 : 그래서 당신은 다음과 동일하다는 것을 생각할 수 있습니다.

C# 버전의 Add 메서드 안에는 호출하는 데 사용한 바인딩에 대한 정보가 없습니다. Add 메서드는 C# 컴파일러에서 readonly 바인딩에 대한 참조를 전달하지 못하도록 데이터를 변경한다고 선언 할 수 없습니다. readonly 키워드는 list 바인딩을 완전히 새로운 List으로 덮어 쓰지 못하도록하지만, 사용자가 가지고있는 데이터의 변경을 막을 수는 없습니다. C#을 사용하면 readonly 바인딩 값을 변경할 수 없지만이 경우 값은 데이터 자체가 아니라 데이터를 가리키는 포인터입니다.

녹이면 메소드가 기본 데이터를 변경해야하는 경우 첫 번째 인수를 self 또는 으로 선언해야합니다.

self의 경우 데이터는 으로 변경되어으로 옮겨지고 더 이상 원본 제본을 사용할 수 없습니다. 호출자가 더 이상 바인딩을 사용할 수 없기 때문에 메서드가 데이터를 변경하는지는 중요하지 않습니다.

변경 가능한 참조 인 경우 &mut self의 경우 Rust는 원본 바인딩도 변경할 수있는 경우에만 만들 수 있습니다. 원래 바인딩이 불변 인 경우 컴파일 오류가 발생합니다.push이 을 예상하기 때문에 v.pushv이 불변 일 경우 호출 할 수 없습니다.

제한적일 수 있으므로 Rust는 필요한 안전성을 정확히 인코딩하기 위해이 동작을 미세 조정할 수있는 도구를 제공합니다. C# 동작에 가까운 것을 얻으려면 RefCell 래퍼 (또는 다른 여러 래퍼 유형 중 하나)를 사용할 수 있습니다. RefCell<Vec<T>> 자체가 기능을 풀어서 내부의 Vec을 수정할 수 있도록 변경할 수 있어야합니다.