Java, C# 및 C ++가 범위가없는 이유는 무엇입니까?
문제
아다, 파스칼 그리고 다른 많은 언어들은 하위 유형의 정수를위한 방법 인 범위를 지원합니다. 범위는 값 (첫 번째)에서 다른 값 (마지막)까지의 서명 된 정수 값입니다. OOP에서 동일하게 수행하는 클래스를 쉽게 구현할 수는 있지만 기능을 기본적으로 지원하면 컴파일러가 추가 정적 검사를 수행 할 수 있다고 생각합니다.
범위에 정의 된 variabile이 "오버 플로우"런타임, 즉 입력 불량으로 인해 "오버 플로우"런타임이 진행되지 않는지 정적으로 확인하는 것은 불가능하다는 것을 알고 있습니다. 나는 생각한다 계약에 의한 디자인 접근 (에펠) 및 사양# ( C# 계약 ), 더 일반적인 해결책을 제공합니다.
C ++, C# 및 Java에서 컴파일 시간에 정적 외부 할당을 확인하는 간단한 솔루션이 있습니까? 어떤 종류의 정적 분석?
편집하다: "범위"는 다른 목적으로 사용될 수 있음을 이해합니다.
- 반복자
- 열거 자
- 정수 하위 유형
포메러는 C* 언어로 쉽게 매핑 할 수 있기 때문에 후자에 집중할 것입니다. 닫힌 값, 즉 음악 볼륨과 같은 닫힌 값, 즉 1에서 100까지의 범위에 대해 생각합니다. 값으로 증가하거나 줄이고 싶습니다. 정적 오버플로의 경우 컴파일 오류를 원합니다.
volume=rangeInt(0,100);
volume=101; // compile error!
volume=getIntFromInput(); // possible runtime exception
감사.
해결책
서브 랜지 유형은 실제로 실제로 유용하지 않습니다. 우리는 종종 고정 길이 배열을 할당하지 않으며 고정 크기의 정수에 대한 이유도 없습니다. 일반적으로 우리가 고정 크기의 배열을 볼 수있는 곳은 열거 역할을하고 있으며, 더 나은 ( "무거운") 솔루션이 있습니다.
서브 랜지 유형은 또한 유형 시스템을 복잡하게 만듭니다. 고정 상수보다 변수간에 제약을 가져 오는 것이 훨씬 더 유용합니다.
(정수는 모든 현명한 언어로 임의의 크기 여야한다는 의무적으로 언급합니다.)
다른 팁
Java는 버전 1.4 이후로 키워드를 주장했습니다. 계약으로 프로그래밍을하는 경우 적절한 과제를 확인하는 데 자유롭게 사용할 수 있습니다. 특정 범위 내에 속한 객체 내부의 모든 변이 속성은 설정하기 전에 확인해야합니다. 당신은 또한 불법 행위를 던질 수 있습니다.
범위 유형이없는 이유는 무엇입니까? 내 생각에 오리지널 디자이너는 C ++에서 하나를 보지 못했고 그들이 올바르게하려고하는 다른 기능만큼 중요하다고 생각하지 않았다는 것입니다.
범위는 그 범위를 통해 무언가를 할 수있을 때 가장 유용합니다. 그것은 폐쇄를 의미합니다. Java 및 C ++의 경우 적어도 범위 유형은 반복자에 비해 성가신 일입니다. 왜냐하면 해당 범위에서 수행 할 작업을 정의하기 위해 내부 클래스를 정의해야하기 때문입니다.
Pascal (및 Delphi)은 서브 랜지 유형을 사용하지만 서수 유형 (정수, 숯 및 부울)으로 제한됩니다.
여분의 유형 검사가있는 정수입니다. 수업을 사용하여 다른 언어로 그것을 가짜로 만들 수 있습니다. 이것은 더 복잡한 범위를 적용 할 수 있다는 이점을 제공합니다.
C ++의 경우, 제한된 값 변수에 대한 LIB가 현재 구현되고 있으며 부스트 라이브러리에서 제안 될 것입니다. http://student.agh.edu.pl/~kawulak/constraind_value/index.html
C#에서는 다음을 수행 할 수 있습니다.
foreach(int i in System.Linq.Enumerable.Range(0, 10))
{
// Do something
}
C ++를 사용하면 템플릿을 통해 이러한 유형을 구현할 수 있으며 이미 수행 할 수있는 몇 가지 라이브러리가 있다고 생각합니다. 그러나 대부분의 경우 혜택이 너무 작아서 추가 복잡성과 편집 속도 페널티를 정당화 할 수 없다고 생각합니다.
정적 인제는 이미 존재합니다. 부스트에는 a가 있습니다 BOOST_STATIC_ASSERT
, 그리고 Windows에서 Microsoft의 ATL 라이브러리가 비슷한 것을 정의한다고 생각합니다.
boost::type_traits
그리고 부스트 :: MPL은 아마도 이와 같은 것을 구현하는 데 가장 친한 친구 일 것입니다.
자신만의 유연성은 언어에 내장하는 것보다 낫습니다. 예를 들어 산술을 포화하려면 범위 값을 벗어난 값에 대한 예외를 던지는 대신 어떨까요? 즉
MyRange<0,100> volume = 99;
volume += 10; // results in volume==100
나는 C ++의 경우 Tom Hawtin 응답에 (내가 동의하는 경우), 범위의 존재는 그들이 일반적인 언어 행동에 일관성을 원한다면 배열에 액세스 할 때, 어쨌든 범위 점검되지는 않습니다. C#과 Java의 경우, 결정은 성능에 근거한 것이라고 생각합니다. 범위를 확인하는 것은 부담을 부과하고 컴파일러를 복잡하게 할 것입니다.
범위는 주로 디버깅 단계에서 유용합니다. 이론적으로 (이론적으로) 범위 위반은 절대로 발생하지 않아야합니다. 따라서 레인지 점검은 언어 자체 내부가 아닌 사전 및 사후 조건에서 구현하는 것이 좋습니다. 릴리스 빌드를 생성 할 때 제거 할 수 있습니다.
이것은 오래된 질문이지만 업데이트하고 싶었습니다. Java는 범위가 매력적이지 않지만 실제로 기능을 원한다면 사용할 수 있습니다. 커먼즈 랭 여기에는 여러 가지 범위 클래스가 있습니다 내부:
IntRange ir = new IntRange(1, 10);
기괴하게, 이것은 Commons Math에는 존재하지 않습니다. 나는 부분적으로 받아 들여진 답변에 동의하지만, 특히 테스트 사례에서 범위가 쓸모가 없다고 생각합니다.
JSR-305는 범위에 대한 지원을 제공하지만 이것이 언제 Java의 일부가 될지 모르겠습니다.