openlang

유니온의 페이로드에 접근하면 패닉이 나요

안녕하세요, 이것 때문에 좀 미치겠네요. 이 꽤 괜찮은 윈도 라이브러리(https://github.com/ypsvlq/wio)를 사용하면서 이 안내(https://github.com/ypsvlq/wio/tree/master?tab=readme-ov-file#wayland)에 따라 wayland API에 접근하려고 해요.

그런데 .backend 유니온에 어떤 값으로 접근해도 바로 invalid enum value 패닉이 나고 원인을 모르겠어요. 유니온에 잘못 접근했다면 컴파일에서 거부할 것 같고, 타입을 살펴봐도 field_names는 예상대로인데, 런타임에 맞는 멤버(여기서는 .wayland)를 쓰든 틀린 멤버(.x11)를 쓰든 패닉이 나요. 접근 시점에 그 값이 undefined일 만한 이유도 찾지 못했어요.

대체 무슨 일인가요??

영어에서 번역원문 보기

이어지는 대화 5

서로의 근거를 따라
  1. 고유 링크

    잘못된 값을 가진 enum으로 switch를 수행할 때 안전 검사가 invalid enum value를 발생시킵니다.

    유니온 필드 접근도 안전 검사를 하며, 이 오류 메시지로 보아 switch를 사용하는 것 같습니다.

    why17가 말했듯, 유니온에 아마 undefined가 들어 있어서 태그도 undefined일 겁니다.

    영어에서 번역원문 보기
  2. 고유 링크

    그 부분 코드를 읽어 보면 여기에 유니온은 없어 보이고, 빌드하는 os와 대상에 따라 컴파일 타임에 백엔드를 고릅니다.

    wio.init를 호출한 뒤에는 백엔드가 초기화되어야 하고(아니면 초기화가 오류를 반환해야 합니다), wio.init가 실행되어 backend.init(options)를 호출하기 전에는 백엔드 값들이 초기화되지 않아 그 시점의 기본값은 전부 undefined입니다:

    https://github.com/ypsvlq/wio/blob/dd0f273fdbbd1ced2a8e716ea3a5526a6c4d83cf/src/unix.zig#L20-L98

    라이브러리가 undefined로 초기화한 컨테이너 수준 변수와 싱글턴에 이렇게 많이 의존하는 게 이해되지 않고, 저라면 이 점 때문에 다른 라이브러리를 고를 것 같습니다.

    wio가 백엔드에 위임하는 대신 정적으로 선택한 백엔드를 일반 struct의 필드에 넣으면, 초기화 전부터 쓸 수 없는 상태로 존재하는 싱글턴을 피할 수 있습니다.

    여기저기 전역을 사용하며 API에서 세부 사항을 숨기는 데 지나치게 집중한 것 같아요.

    영어에서 번역원문 보기
  3. 고유 링크

    제가 말하는 건 wayland와 x11 구현을 담은 유니온인 unix.Window예요.

    제가 완전히 놓친 건 오류가 크기 변경 이벤트 콜백 안에서 난다는 점이고, 그 콜백이 Window.init 중에 바로 호출되는 모양인데 저는 지금 초기화 중인 바로 그 윈도를 담을 변수를 읽고 있으니, 그게 이 문제를 설명하겠네요. 이것도… 마음에 썩 들지는 않는 설계 선택이지만, 괜찮은 다른 라이브러리를 아직 못 찾았어요.

    윈도 변수 자체가 undefined라면 .backend 멤버를 읽는 순간 먼저 실패해야 할 것 같은데, 특히 유니온 접근에서 실패한다는 점이 좀 신기하네요?

    영어에서 번역원문 보기

같은 질문의 다른 갈래

  1. 정리 블록이 실제로 실행될 때까지 가변 빌림을 미루기

    Rust에서 Java의 try { ... } finally { ... }와 비슷하게 패닉에도 안전한 구조를 만들고, try와 finally 블록이 같은 값을 각각 가변으로 빌리게 하려면 어떻게 해야 하나요? 원하는 건 정상…

    답글 2최근 활동 rust
  2. 포인터를 통해 문자 배열 입력받기

    키보드에서 char 배열들로 입력을 받으려고 하면 프로그램이 계속 죽습니다. 키보드에서 char 배열을 읽어서 저장하는 간단한 방법이 뭘까요?

    답글 2최근 활동 c
  3. 전역 변수에 의존하지 않는 입력 함수를 만들 수 있나요?

    사용자 입력을 처리하고 걸러 낸 뒤, 호출한 함수에 결과 문자열을 돌려주는 함수를 만들고 싶습니다. 아래 예처럼 전역 변수를 선언하지 않고도 가능할까요?

    답글 2최근 활동 c