Base

재할당 불가와 참조 불변성의 차이

Dr.Mlem 2024. 12. 4. 16:22
Q1.
const args = {};
 
이렇게 JS에서 상수를 선언했는데,
이 {} 안에다가 키-값 쌍을 추가해줄 수 있어? 상수는 값을 못 바꾸는것 아니였어?
 
 
 
A1.

ChatGPT의 말:

 

좋은 질문이야! const에 대해 정확히 이해하면 이 상황이 더 명확해질 거야.

const로 선언한 변수

const는 변수 자체를 재할당하지 못하게 막는 거지, 변수 내부의 이나 상태를 변경하는 걸 막는 건 아니야. 예를 들어, 객체를 const로 선언하면 그 객체의 **참조(reference)**는 변경할 수 없지만, 객체 내부의 속성은 수정할 수 있어.


예제 코드로 확인해 보자:

const args = {}; // 빈 객체 선언

// 객체 내부에 키-값 쌍 추가
args.name = "Alice";
args.age = 25;

console.log(args); 
// 출력: { name: "Alice", age: 25 }

여기서 중요한 점은 args라는 변수 자체가 다른 객체로 재할당될 수 없다는 것이지. 예를 들어, 아래 코드는 에러를 발생시켜:

const args = {};
args = { key: "value" }; // TypeError: Assignment to constant variable.

핵심 정리

  • const로 선언한 객체나 배열의 내용은 변경 가능: 키-값 추가, 수정, 삭제 가능.
  • const로 선언된 변수는 재할당 불가능: args = {...} 같은 코드는 에러.

이건 const가 변수의 **참조(reference)**를 고정하기 때문이야. 객체나 배열은 참조형 데이터이므로, 참조를 고정해도 내부 상태는 변할 수 있어. 이해됐지? 😊

 
 
 
Q2.

나의 말:

이건 다른 프로그래밍 언어에서도 통용되는 개념인가?
 
 
 
A2.

ChatGPT의 말:

 

const와 같은 개념은 다른 프로그래밍 언어에서도 어느 정도 유사하게 동작할 수 있지만, 언어마다 상수의 정의와 동작 방식이 다르기 때문에 JavaScript의 방식이 다른 언어에서 항상 통용된다고 볼 수는 없어. 각 언어의 동작 방식을 비교해 볼게!


1. JavaScript

  • const는 변수의 재할당을 막을 뿐이고, 참조형 데이터(객체, 배열)의 내부 수정은 허용.
  • 예:
const arr = [1, 2];
arr.push(3); // [1, 2, 3]
arr = [4, 5]; // TypeError: Assignment to constant variable.
 

2. Python (const 개념이 없음, 하지만 유사한 상황 예시)

Python에서는 기본적으로 상수 선언을 지원하지 않지만, 관습적으로 대문자 변수명으로 상수를 표현하고, 재할당을 피하려고 노력해.

MY_CONST = [1, 2]
MY_CONST.append(3)  # 내부 변경 가능
MY_CONST = [4, 5]   # 재할당 가능 (Python에서는 막지 않음)

다만, frozen 객체 같은 방식을 사용하면 내부 수정도 막을 수 있어:

from types import MappingProxyType
MY_CONST = MappingProxyType({"key": "value"})  # 읽기 전용
MY_CONST["key"] = "new value"  # TypeError: 'mappingproxy' object is immutable

3. C++

C++에서는 const 키워드가 완전히 다른 의미를 가지는데, 값 자체나 참조를 변경하지 못하게 강력히 막는 역할을 한다.

  • 기본 변수:
const int x = 10;
x = 20; // Error: assignment of read-only variable
  • 포인터의 경우 참조 여부에 따라 다름:
const int *ptr = &x; // 포인터로 가리키는 값은 수정 불가
*ptr = 20; // Error
ptr = &y;  // 가능 (포인터는 변경 가능)

int *const ptr2 = &x; // 포인터는 고정, 값은 수정 가능
*ptr2 = 20; // 가능
ptr2 = &y;  // Error

4. Java

Java에서는 final 키워드를 사용해 상수를 정의해. final이 적용된 객체 참조는 변경할 수 없지만, 참조한 객체의 내부는 수정할 수 있어.

final List<Integer> list = new ArrayList<>();
list.add(1); // 가능
list = new ArrayList<>(); // Error: cannot assign a value to final variable 'list'

5. Rust

Rust에서는 let과 const 키워드가 존재하며, 둘 다 엄격한 제약을 가짐.

  • const: 완전히 불변 상수, 컴파일 타임에 값이 결정되고 변경 불가.
  • let + mut: 가변 변수.
  • let: 참조형 데이터라도 기본적으로 불변.
let arr = vec![1, 2, 3];
arr.push(4); // Error: cannot borrow as mutable

let mut arr = vec![1, 2, 3];
arr.push(4); // 가능

요약

  • 대부분의 언어에서 재할당 불가참조 불변성을 혼동하지 않도록 주의해야 해.
  • JavaScript의 방식(참조는 고정, 내부는 변경 가능)은 Python이나 Java와 약간 유사.
  • Rust, C++ 같은 언어는 더 엄격한 제약을 가지고 있어.
  • 언어를 사용할 때 상수 키워드가 참조에 적용되는지, 값에 적용되는지 명확히 이해하는 게 중요해! 😊

어떤 언어에서 더 깊게 탐구해 보고 싶어? 😊

'Base' 카테고리의 다른 글

클래스 다이어그램에서의 IsA, HasA  (1) 2024.12.13
"동적"이란게 뭐지?  (0) 2024.12.11
시스템/웹에서의 경로  (0) 2024.12.02
지역 메서드라는건 없나?  (0) 2024.11.29
컴포넌트내의 코드의 분리, 코드의 분리  (2) 2024.11.28