선택 사항과 널 입력 가능 유형의 차이점은 무엇입니까


15

스위프트가 Optionals있습니다. C #에는 Nullable유형 이 있습니다.

둘 다 동일한 목적을 제공한다고 말할 수있는 한, 일부 유형의 값 외에도 변수에 값이 있는지 정의되지 않은 (초기화되지 않은) 정보가 저장됩니다.

질문 IS는 Optionals단지 Nullable다른 이름으로 유형 또는 다른 개념적인 차이가 있습니까?

다시 말해서, 개념 자체에 대해 이야기 Optionals하거나 Nullables또는를 갖지 않는 언어의 맥락에서 말하는 용어가 사용 되는가?

해당 기능을 언어로 구현할 때 내가 이름을 입력 Optionals<T>하든 또는Nullable<T>


언어에 구애받지 않는 관점에서 그것들은 동일합니다. 즉, 언어는 개념을 차별화 할 수 있습니다 (예 : 패턴 일치의 시행 여부).
토마스 대한 수정 사항

C #도 옵션을 가질 수 있습니다 (단순한 패턴 일뿐
Den

2
널 참조 (또는 포인터가있는 언어의 경우 NULL 포인터)를 사용하는 것은 일부 언어가 선택적 값 (예 : 하나의 값을 갖거나 전혀 값이없는 컨테이너)을 나타내는 데 사용하는 핵입니다. 이는 참조 (또는 포인터)를 기반으로하는 선택적 유형 만 고려할 수 있다는 제한 사항이 있습니다. 예를 들어 Java에서는 정수를 객체에 래핑하지 않으면 정수를 선택적으로 만들 수 없습니다. 다른 언어는 다른 유형을 래핑 할 수있는 일반 유형으로 선택적 유형을 제공합니다 (예 : 아마도 Haskell, Option in Scala 등).
Giorgio

답변:


5

매우 유사하게 작동하지만 다른 의미가 있습니다. 모든 사람하지만 마이크로 소프트 (여기 눈 롤 삽입)를 사용 null하고 nullable참조 만의 맥락이다. OptionsMaybes일반적으로 참조 투명성 수단은 기준 값과 별 차이가없는 경우에는 특히, 함수형 프로그래밍 언어, 참조 및 값 모두를 참조하는 것으로 이해된다.

다른 말로하면, 개념 자체, 또는하지 않는 언어의 맥락에서 얘기 Optionals하거나 Nullables,이 사용되는 용어 상관이야?

Options광범위한 관중들 사이에 혼동을 최소화하는 용어입니다. C # 프로그래머만 Nullable이 가치 유형에 잠재적으로 적용되는 것으로 생각할 것 Option입니다.


Microsoft와 SQL 디자이너를 제외한 모든 사람들은 당신이 생각하는 것 같습니다.
Jules

9

.NET에는 참조 (int, double, structs, enums 등)의 두 가지 범주 유형이 있습니다. 이들의 차이점 중 하나는 참조가 될 수 있지만 null값은 할 수 없다는 사실입니다 . 따라서 값 유형이 있고 "선택적"또는 "알 수없는"의미를 전달하려는 경우이를 사용하여 값을 지정할 수 있습니다 Nullable<>. 주 Nullable<>유형에 의해 제약된다 (그것은에만 값 형식을 적용합니다 where T : struct절). Nullable<>또한 컴파일러로부터 특별한 이익을 얻음으로써 null값이 보호됩니다 NullReferenceExceptions.

string x = null;
x.ToString(); // throws a NullReferenceException

int? y = null;
y.ToString(); // returns ""

(예 등 스칼라, F 번호, 하스켈, 스위프트 등) 함수형 언어에서 그것은 일반적입니다 null존재하지 . 이는 전체 사람들이 존재를 나쁜 생각null 으로 간주 하고 언어 디자이너가이 문제를 허용하지 않음으로 해결하기로 결정했기 때문입니다.

다시 말해 , 이러한 언어 로 가치없는 것을 표현할 방법이 필요하다는 것을 의미합니다 . Option유형을 입력하십시오 (명칭은 다양 Maybe하며 Haskell 에서 호출 됩니다). Nullable값이 "없음"또는 "알 수 없음"인 경우를 추가하기 위해 유형을 래핑한다는 점에서 비슷한 작업을 수행합니다 .

실제 차이점은 구현하는 언어로 제공되는 추가 기능에 있습니다 Option. 예를 들어 Option.map(의사 코드로) :

function Option<T2> Option.map(opt: Option<T1>, mapFunc: T1 -> T2) {
    if (opt is None) return None
    else return Option<T2>(mapFunc(opt.Value))
}

같은 체인 함수 Option.map는 C #의 모든 곳에서 볼 수있는 일반적인 null check 상용구를 피하는 강력한 방법입니다.

if (service == null)
    return null;
var x = service.GetValue();
if (x == null || x.Property == null)
    return null;
return x.Property.Value;

C #의 Nullable 해당 항목은 다음과 같습니다.

public static Nullable<T2> Map<T1, T2>(this Nullable<T1> nullable, Func<T1, T2> f)
    where T1 : struct
    where T2 : struct
{
    if (!nullable.HasValue) return (T2?)null;
    else return (T2?) f(nullable.Value);
}

그러나 C #에서는 값 형식에 대해서만 작동하기 때문에 유틸리티가 제한적입니다.

C #의 새 버전은 "널 전파"연산자 ( ?.)를 제공합니다.이 연산자 Option.map는 메서드 및 속성 접근 자에만 적용 할 수 있다는 점만 제외 하면 함수 와 비슷합니다 . 위의 샘플은 다시 작성됩니다

return service?.GetValue()?.Property?.Value;

C #은 불완전한 기능 언어입니다 (F #과 동일). 또한 F #에는 null이 있습니다.
Den

C # 6에는 null 값 강제가 있으므로 최소한 일부 코드가 최신 상태가 아닙니다. github.com/dotnet/roslyn/wiki/… roslyn.codeplex.com/discussions/540883
Den

또한 옵션은 쉽게 구현하는 방법은 다음과 같습니다 github.com/louthy/language-ext

1
@Den : C #은 OOP쪽으로 기울이고 F #은 FP쪽으로 기울입니다. 기본적으로 커링 및 변경이 불가능하다는 것은 C #이 심각한 기능적 프로그래밍에 적합하지 않음을 의미합니다. 답변 끝에 null 전파를 언급했습니다. 옵션은 실제로 C #에서 구현하기 간단하지만 질문에서 벗어났습니다.
AlexFoxGill

4
@Den 의견에 단어의 선택이 잘못되었다고 생각합니다. 부적절한 기능 언어는 부작용을 허용하는 기능 언어입니다. C #에는 일부 기능적 기능이있을 수 있으며이를 효과적으로 사용할 수 있지만 기능적 언어는 아닙니다. 언어가 100 % 기능적이라는 의미는 아니지만 F #은 대부분 기능적인 언어 인 OCaml에 매우 가깝습니다. 기능적 패러다임과의 편차는 대부분 존재하므로 외부 .NET 코드와 상호 운용 될 수 있습니다. 적절한 사례는 nullF # 유형에 유효한 값이 아닙니다.
Doval
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.