숫자 연산과 조회 결과를 예측하고, 실행을 멈추는 배열 접근을 고쳐 보세요. 예제를 통해 검사를 통과한 뒤 프로그램이 어떻게 동작하는지 확인합니다.
첫 프로그램에서 토파즈를 설치하세요. 두 예제는 별도 파일로 저장하고 각 파일이 있는 폴더에서 실행합니다.
정상 값 관찰하기
다음 코드를 runtime-behavior.tpz로 저장하세요.
let 값들 = [10, 20]
print("int: {7 / 2} {-7 % 3}")
print("float: {1.5 + 1.5}")
print("safe: {값들.get(9)}")topaz run runtime-behavior.tpz를 실행하세요.
int: 3 -1
float: 3.0
safe: None7 / 2는 소수 부분을 0 방향으로 버리므로 3이 됩니다. -7 % 3은 나머지가 피나눗수의 부호를 따르므로 -1이 됩니다. 1.5 + 1.5는 3.0으로 출력됩니다.
값들.get(9)는 인덱스 9에 원소가 없어서 None을 반환합니다. get은 값 없음을 반환값으로 나타내므로 프로그램은 계속 실행됩니다.
print는 문자열을 받아 출력하고 줄을 바꿉니다. 보간식은 호출 전에 숫자와 Option을 텍스트로 바꿉니다. 한 줄 출력에는 print를 쓰세요. 독립 함수 println은 없습니다.
잘못된 배열 인덱스 확인하기
두 번째 예제를 intentional-fault.tpz로 저장하세요.
let 과제들 = ["Run first program", "Build application"]
print(과제들[2])topaz run intentional-fault.tpz를 실행하세요. 0이 아닌 상태로 종료하고 잘못 접근한 위치를 표시합니다.
error[TPZ4001]: index 2 is out of bounds for an array of length 2
--> intentional-fault.tpz:2:7
|
2 | print(과제들[2])
| ^^^^^^
배열에는 인덱스 0과 1의 원소 두 개가 있습니다. 과제들[2]를 과제들[1]로 바꾸고 다시 실행하면 Build application을 출력합니다. 없는 인덱스도 입력으로 받을 수 있다면 과제들.get(2)를 쓰고 None을 처리하세요.
실행 오류(fault)는 실행을 멈춥니다. 후위 ?, 선택 연산자, concurrent로 잡을 수 없습니다. None과 Err는 프로그램에서 처리할 수 있는 값입니다.
실패 결과 구분하기
| 상황 | 결과 |
|---|---|
| 값이 없음 | get의 None 같은 Option |
| 작업이 실패 원인을 반환 | Ok나 Err를 담은 Result |
| 실행 중 잘못된 연산에 도달 | 실행 오류와 0이 아닌 프로세스 종료 상태 |
| 실행 전 소스가 잘못됨 | topaz check의 진단 |
int는 부호 있는 64비트 정수입니다. 정수 범위를 넘으면 실행 오류로 멈춥니다. float는 IEEE-754 binary64 연산을 사용하므로 십진 소수를 계산할 때 반올림이 필요할 수 있습니다.
실행 중 다음 조건에 도달하면 실행 오류가 납니다.
| 연산 | 잘못된 조건 |
|---|---|
| 배열 직접 인덱싱 | 배열 밖의 인덱스 |
| 정수 나눗셈이나 나머지 | 제수가 0 |
| 정수 산술 | 결과가 정수 범위를 넘음 |
| 범위 순회 | 증가량이 0 |
| 정수 거듭제곱 | 지수가 음수 |
match | 값과 일치하는 분기가 없음 |
검사기는 잘못된 상수 산술을 실행 전에 거부할 수 있습니다. 실행 중에 계산하는 값은 연산 전에 입력을 확인하세요.
호출 깊이의 상한은 모든 실행 경로에서 1000 프레임입니다. 아직 끝나지 않은 중첩 호출 1000개를 뜻합니다. 더 깊은 호출은 호출 위치에서 TPZ5009를 보고합니다. 이 상한을 높이는 명령줄 옵션은 없습니다.
안정적으로 유지되는 것
문자열은 유니코드 스칼라의 정확한 순서로 비교합니다. 스칼라는 서로게이트 범위를 제외한 유니코드 코드 포인트 하나입니다. 토파즈는 서로 다른 스칼라 나열을 같은 표기로 자동 정규화하지 않습니다. 예를 들어 미리 조합한 "é"와 "é"는 비슷하게 보여도 같지 않습니다.
배열은 원소 순서를 유지합니다. Map 키 스냅샷은 삽입 순서를 유지합니다. 다른 컬렉션 연산과 콜백은 각 연산에 지정된 순서를 따릅니다.
record, enum, newtype 값을 출력하면 해당 타입의 생성자 이름을 유지합니다. 출력 형태는 Name { field: value }, Name.Variant, Name(value)입니다. 실행 대상마다 값을 저장하는 방식은 달라도 언어가 정한 출력과 실행 규칙은 유지합니다.
값 처리는 Null·Option·결과·fault, 시간 초과는 동시성, 변환 함수는 코어 라이브러리에서 확인하세요. 문자열과 템플릿은 스칼라 위치를 설명합니다.