함수 매개 변수에 대한 익명 구조체 유형
Typescript에서 다음을 수행 할 수 있습니다.
function foo(param: { a: string, b: number }) { }
매개 변수 유형을 다음과 같이 명명 된 유형으로 명시 적으로 선언하지 않고 객체를받는 함수를 선언하려면 :
interface Parameter {
a: string;
b: number;
}
function foo(param: Parameter) {}
Rust에서이 작업을 수행 할 수있는 방법이 있습니까? 아니면 매개 변수 유형을 명명 된 유형으로 명시 적으로 선언해야합니까?
답변
Rust는 다음과 같이 튜플, 배열 및 구조체의 함수 매개 변수에 대한 패턴 분해를 가지고 있습니다.
fn f((a, b): (u32, i32), [x, y, z]: [String; 3]) { }
struct A { a: u32, b: String }
fn g(A { a, b }: A) { }
그러나 객체가 단순히 rust에 존재하지 않기 때문에 명명되지 않은 유형 / 객체에 대한 구문이 없습니다. Rust가 이것에 대한 구문을 가지고 있다고 상상해보십시오.
fn f(param: {a: String, b: String}) {} // Invalid code!
누군가 그 함수를 어떻게 부르겠습니까? 이 유형의 인스턴스를 생성하는 방법은 없습니다. 자바 스크립트 (/ typescript)에서는 동적 타이핑 때문에 가능하지만, Rust에서는 그것을 구성 할 수있는 타입을 알아야합니다.
함수에서 키워드 인자를 가짜로 만드는 데 관심이 있다면 도움이 될 것입니다. Rust에서 * fake * 키워드 스타일 함수 인자를 가장 잘하는 방법은 무엇입니까?
튜플에 이름을 지정하고 매개 변수에 이름을 지정하려면 bindings_after_at
이 구문을 활성화 하는 불안정한 기능 이 있습니다.
#![feature(bindings_after_at)]
fn f(my_tuple @ (a, b): (u32, u32)) {
println!("this: {:?}", my_tuple);
println!("is the same as: {:?}", (a, b));
}
// or this
fn g(arr @ [.., tail] : [u32; 5]) {
println!("this: {}", arr[4]);
println!("is the same as: {}", tail);
}
튜플을 사용할 수 있습니다.
fn foo(param: (String, usize)) {
let a: String = param.0;
let b: usize = param.1;
}
구조체와 같은 이름이 지정된 필드가 아닌 튜플 값이 인덱싱됩니다. 튜플을 분해하면 값을 추적하기가 조금 더 쉬워집니다.
fn foo((a, b): (String, usize)) {
// you can now access `a` and `b` here
}
러스트에서는 공칭 유형 시스템이 있고 코드가 구조적 유형 시스템의 예이기 때문에 이러한 작업을 수행 할 수 없습니다. wikipedia에서 읽을 수 있습니다.https://en.wikipedia.org/wiki/Nominal_type_system https://en.wikipedia.org/wiki/Structural_type_system
구조적 유형 시스템에서 유형은 필드의 집합 일 뿐이며 이름과 정의는 중요하지 않습니다. 대조적으로, 명목 유형 시스템은 선언이 다르지만 동일한 필드 세트를 가진 2 개의 유형을 다른 것으로 취급합니다 (즉, 해당 유형의 이름이 내용보다 중요 함).
Rust는 명목상을 선택했습니다. 그 이유는 스트라이커이고 유형 수준에서 프로그램의 일부 속성을 적용 할 수 있기 때문입니다. 이 예를 고려하십시오.
struct Employee(String);
struct Customer(String);
fn handle_order(employee: Employee, customer: Customer){}
프로그래머가 실수를해서라고 부르면 handle_order(customer, employee)
구조적 타이핑을하는 언어에서는 알아 차리지 못하지만 명목 타이핑에서는 컴파일 오류를 유발하는 실수입니다.
또한 프로그래머가 유형 정의를 변경해야하는 상황이있을 수 있습니다 (예 : Employee
. 이 경우 Employee의 모든 사용이 수정되었을 때 리팩토링이 완료되었음을 확신 할 수 있습니다. 구조적 유형이있는 프로그램에서는 대신 고객을 보내는 코드가있을 수 있으므로 구조적 유형의 프로그램을 리팩토링하는 것이 조금 더 어렵 기 때문에 확신 할 수 없습니다.
Rust에서 명목상 타이핑의 또 다른 유명한 예는 수명 입니다. 정의 된 유형이 같고 수명이 다른 유형의 변수는 실제로 다른 명목 유형을 갖습니다. 그리고 모든 Rusts 안전은 이것에 기초합니다.
Typescript는 JavaScript로 매핑하기가 더 쉽기 때문에 구조적 유형을 사용합니다.