함수 매개 변수에 대한 익명 구조체 유형

Dec 23 2020

Typescript에서 다음을 수행 할 수 있습니다.

function foo(param: { a: string, b: number }) { }

매개 변수 유형을 다음과 같이 명명 된 유형으로 명시 적으로 선언하지 않고 객체를받는 함수를 선언하려면 :

interface Parameter {
    a: string;
    b: number;
}

function foo(param: Parameter) {}

Rust에서이 작업을 수행 할 수있는 방법이 있습니까? 아니면 매개 변수 유형을 명명 된 유형으로 명시 적으로 선언해야합니까?

답변

3 Natrix Dec 24 2020 at 05:03

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);
}
2 IbraheemAhmed Dec 24 2020 at 03:51

튜플을 사용할 수 있습니다.

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
}
2 AngelicosPhosphoros Dec 24 2020 at 19:11

러스트에서는 공칭 유형 시스템이 있고 코드가 구조적 유형 시스템의 예이기 때문에 이러한 작업을 수행 할 수 없습니다. 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로 매핑하기가 더 쉽기 때문에 구조적 유형을 사용합니다.