Rust 구조체에서 변수를 초기화하는 더 빠르고 짧은 방법이 있습니까?


102

다음 예제에서 필자는 필드 선언에서 구조체의 각 필드에 값을 할당하는 것을 선호합니다. 또는 각 필드에 대해 하나의 추가 문을 사용하여 필드에 값을 할당합니다. 내가 할 수있는 것은 구조체가 인스턴스화 될 때 기본값을 할당하는 것뿐입니다.

더 간결한 방법이 있습니까?

struct cParams {
    iInsertMax: i64,
    iUpdateMax: i64,
    iDeleteMax: i64,
    iInstanceMax: i64,
    tFirstInstance: bool,
    tCreateTables: bool,
    tContinue: bool,
}

impl cParams {
    fn new() -> cParams {
        cParams {
            iInsertMax: -1,
            iUpdateMax: -1,
            iDeleteMax: -1,
            iInstanceMax: -1,
            tFirstInstance: false,
            tCreateTables: false,
            tContinue: false,
        }
    }
}

답변:


161

트레이 트를 구현하여 구조체에 대한 기본값을 제공 할 수 있습니다 Default. default기능은 현재처럼 보일 것입니다 new기능 :

impl Default for cParams {
    fn default() -> cParams {
        cParams {
            iInsertMax: -1,
            iUpdateMax: -1,
            iDeleteMax: -1,
            iInstanceMax: -1,
            tFirstInstance: false,
            tCreateTables: false,
            tContinue: false,
        }
    }
}

그런 다음 기본값이 아닌 값만 제공하여 구조체를 인스턴스화 할 수 있습니다.

let p = cParams { iInsertMax: 10, ..Default::default() };

데이터 구조를 약간 변경하면 자동으로 파생 된 기본 구현을 활용할 수 있습니다. 당신이 사용하는 경우 #[derive(Default)]데이터 구조에, 컴파일러는 자동으로 기본 값으로 각 필드를 채우고 당신을위한 기본 기능을 생성합니다. 기본 부울 값은 false이고 기본 정수 값은 0입니다.

정수 필드가 기본적으로 -1이되기를 원하기 때문에 정수의 기본값이 0이면 문제가됩니다. 기본값 -1을 구현하는 새 유형을 정의하고 대신 사용할 수 있습니다.i64 구조체 있습니다. (나는 그것을 테스트하지 않았지만 작동합니다).

그러나, 나는 약간의 데이터 구조를 변경하고 사용하는 것이 좋을 것 Option<i64>대신에 i64. 코드의 컨텍스트를 모르지만 "무한"또는 "최대가 없습니다"라는 특별한 의미를 나타 내기 위해 특수 값 -1을 사용하는 것 같습니다. Rust에서는를 사용 Option하여 선택적으로 현재 가치를 나타냅니다. -1 해킹이 필요하지 않습니다. 옵션은 None또는 Some(x)x가 i64여기에 있는 곳일 수 있습니다. -1이 유일한 음수 값이면 부호없는 정수일 수도 있습니다. 기본값 OptionNone이므로 제안 된 변경 사항에 따라 코드는 다음과 같을 수 있습니다.

#[derive(Default)]
struct cParams {
    iInsertMax: Option<u64>,
    iUpdateMax: Option<u64>,
    iDeleteMax: Option<u64>,
    iInstanceMax: Option<u64>,
    tFirstInstance: bool,
    tCreateTables: bool,
    tContinue: bool,
}

let p = cParams { iInsertMax: Some(10), ..Default::default() };

1
고마워요, 빨리 읽었지만 더 잘 이해하기 위해 다시 읽겠습니다. I believe zero, false, ""등과 같은 일부 언어에서 사용하는 "자연스러운"기본값이 나에게 적합합니다. 해결해야 할 작은 "문제"보다 더 넓은 의미가 있음을 이해합니다. 예를 들어 진술하는 능력. "iVal : i64 = 0"은 내 더 넓은 요구를 해결할 수 있지만 그렇게되지 않을 것 같습니다. "# [deriving (Default)]"는 내가 원하는 대부분을 해결할 것입니다. 테스트 프로그램에서 -1을 사용하는 이유를 잘 모르겠지만 필요하지 않습니다 (역사적). 필드가 정의 된 현장에서 값을 할당 할 수 있으면 매우 유용합니다 (IMHO).
Brian Oh

9
@BrianOh, 접선 적으로 "구조 필드의 기본값"(예 :) struct Foo { val: i64 = 0 }이 제안되었으며 이후 버전에 나타날 수 있습니다.
huon

그것이 IMO- "struct foo {...."로 구현 되었다면 좋을 것입니다. 내 질문에 작성된 구조체를 기본값으로 사용하여 제안한대로 변경했습니다. 그것은 확실히 나에게 더 적합하고 훨씬 더 간결합니다. 구문에 익숙하지 않아서 내가 가진 한 가지 사소한 문제는 모든 기본값에 대한 구문을 알지 못했습니다. IE : "= cParams {iInsertMax : 10, ..Default :: default ()};"를 사용했지만 실제로는 "iInstanceMax"도 기본값이되기를 원합니다. IMO는 "# [deriving (Default)]"를 구조체의 일부로 사용하는 것이 좋지만 대안이 컴파일러에 더 적합하다고 생각합니다.
Brian Oh

2
감사합니다. IMHO 기본값은 기본값이어야합니다. IE. 나는 Default : default 등을 지정할 필요가 없다고 생각한다. 또한 필드가 정의 된 값을 할당받을 수 있어야한다고 생각한다. 그것은 내 단순한 관점에서 볼 때 Rust가 안전하도록 설계되었으며 내 것보다 훨씬 더 넓은 관점이 있다는 것을 알고 있습니다. 언어 (또는 적어도 나)를 배울 때 현재 구현은 약간 번거로운 것 같습니다. Rust는 단순한 언어 IMHO가 아닙니다. 그리고 그것을 단순화하기 위해 더 많이 할 수있는 것이 적어도 저에게는 더 좋습니다.
Brian Oh

2
Default구조체를 구현할 때 모든 필드의 기본값을 정의해야 합니까?
Matthew Stevenson
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.