네임 바인딩

"오늘의AI위키"는 AI 기술로 일관성 있고 체계적인 최신 지식을 제공하는 혁신 플랫폼입니다.
"오늘의AI위키"의 AI를 통해 더욱 풍부하고 폭넓은 지식 경험을 누리세요.

1. 개요

네임 바인딩은 프로그래밍에서 식별자와 해당 식별자가 참조하는 값 또는 메모리 위치를 연결하는 과정이다. 바인딩은 프로그램 실행 전에 이루어지는 정적 바인딩과 실행 중에 이루어지는 동적 바인딩으로 구분된다. 정적 바인딩은 컴파일 시간에 결정되며, 동적 바인딩은 런타임에 결정된다. 동적 바인딩은 다형성을 구현하는 데 사용되며, 늦은 정적 바인딩은 정적 바인딩과 동적 바인딩의 중간 형태이다. 리바인딩은 식별자가 다른 값을 참조하도록 변경하는 것이고, 변형은 참조된 값 자체를 변경하는 것이다.

네임 바인딩
이름 바인딩
개념프로그램의 엔터티와 식별자 간의 연결
역할컴파일러와 인터프리터가 변수와 함수를 메모리 위치에 연결하는 데 사용
유형
바인딩 시간변수가 유형과 값에 바인딩되는 시점
정적 바인딩컴파일 시간에 발생
변수의 유형과 값은 변경할 수 없음
동적 바인딩런타임에 발생
변수의 유형과 값은 변경할 수 있음
늦은 바인딩동적 바인딩의 한 형태
컴파일러 또는 인터프리터는 함수 또는 객체에 대한 호출의 유효성을 런타임까지 확인하지 않음
이점
정적 바인딩컴파일러가 유형 오류를 감지하는 데 도움이 됨
코드 성능 향상에 도움이 됨
동적 바인딩더 많은 유연성을 제공
런타임에 변수의 유형을 변경할 수 있음
단점
정적 바인딩유연성이 떨어짐
동적 바인딩유형 오류를 감지하기 어려움
코드 성능 저하를 초래할 수 있음
기타
예시C++ 및 Java와 같은 언어는 정적 바인딩을 사용
Python 및 JavaScript와 같은 언어는 동적 바인딩을 사용
📚 더 읽어볼만한 페이지
  • 프로그래밍 언어 개념 - 참조
    참조는 프로그래밍에서 메모리 주소나 다른 데이터를 가리키는 값으로, 데이터의 효율적인 전달과 공유를 위해 사용되며, 포인터, 파일 핸들, URL 등이 그 예시이다.
  • 프로그래밍 언어 개념 - 자료형
    자료형은 프로그래밍 언어에서 데이터를 분류하고 관리하는 추상적인 분류 체계로, 값의 표현, 해석 및 구조에 제약 조건을 가하여 프로그램의 정확성을 검증하며, 단순형/복합형, 언어 정의형/사용자 정의형 등으로 분류되고 문자형, 수치형, 부울형 등 다양한 종류가 있다.

2. 바인딩 시간

프로그램 실행 이전에 이름 바인딩이 수행되는 것을 정적 바인딩(또는 초기 바인딩)이라고 한다. 반면, 프로그램 실행 중에 이름 바인딩이 수행되는 것을 동적 바인딩(또는 [[지연 바인딩]] 또는 가상 바인딩)이라고 한다.

정적 바인딩의 예로는 C의 직접적인 함수 호출이 있다. 이 경우 식별자가 참조하는 함수는 런타임에 변경될 수 없다. 동적 바인딩의 예로는 동적 디스패치가 있으며, C++가상 메소드 호출이 이에 해당한다. 다형성 객체의 구체적인 타입은 런타임 전에는 알 수 없기 때문에 실행되는 함수는 동적으로 결정된다.

정적 바인딩과 동적 바인딩의 중간 형태인 늦은 정적 바인딩도 존재한다. 다음 PHP 예시를 통해 살펴보자.

```php
class A
{
public static $word = "hello";
public static function hello() { print self::$word; }
}

class B extends A
{
public static $word = "bye";
}

B::hello();
```

위 예시에서 PHP 인터프리터는 `A::hello()` 내의 `self` 키워드를 클래스 `A`에 바인딩한다. 따라서 `B::hello()`를 호출하면 "hello"가 출력된다. 만약 `self::$word`의 의미가 늦은 정적 바인딩을 따른다면 "bye"가 출력될 것이다. PHP 5.3 버전부터 늦은 정적 바인딩이 지원된다. `self::$word`를 `static::$word`로 변경하면 `static` 키워드는 런타임에 바인딩되어 `B::hello()` 호출 결과는 "bye"가 된다.

2.1. 정적 바인딩 (Static Binding)

정적 바인딩은 프로그램이 실행되기 전에 수행되는 이름 바인딩이다. 정적 바인딩의 예로는 직접적인 C 함수 호출이 있다. 식별자에 의해 참조되는 함수는 런타임 시에 변경될 수 없다. C와 같은 언어에서는 실제 함수가 알려진다.

2.2. 동적 바인딩 (Dynamic Binding)

프로그램이 실행될 때 수행되는 바인딩은 동적 바인딩(또는 지연 바인딩 또는 가상 바인딩)이라고 불린다.

동적 바인딩의 예로는 동적 디스패치가 있으며, 이는 C++ 가상 메소드 호출에서 나타난다. 다형성 객체의 특정 유형은 (일반적으로) 런타임 전에 알 수 없으므로 실행되는 함수는 동적으로 바인딩된다. 예를 들어, 다음과 같은 자바 코드를 보자.

```java
public void foo(java.util.List list) {
list.add("bar");
}
```

`List`는 인터페이스이므로 `list`는 해당 인터페이스의 하위 유형을 참조해야 한다. `list`는 `LinkedList`, `ArrayList` 또는 `List`의 다른 하위 유형을 참조할 수 있다. `add`에 의해 참조되는 메서드는 런타임까지 알 수 없다. 동적 바인딩이 없는 C에서는 유사한 목표를 함수 포인터 유형의 변수 또는 표현식에 의해 지정된 함수를 호출하여 달성할 수 있으며, 해당 값은 런타임에 평가될 때까지 알 수 없다.

2.3. 늦은 정적 바인딩 (Late Static Binding)

늦은 정적 바인딩은 정적 바인딩과 동적 바인딩의 중간쯤에 위치한다. 다음 PHP 예시를 보자.

```php
class A {
static $word = "hello";
static function hello() {print self::$word;}
}

class B extends A {
static $word = "bye";
}

B::hello();
```

이 예시에서, PHP 인터프리터는 함수 `hello()`를 클래스 `A`에 바인드하며, 그래서 `B::hello()`에 대한 호출은 문자열 "hello"를 출력한다. 만약 `self::$word`의 의미가 늦은 정적 바인딩에 기반한다면, 결과는 "bye"가 되었을 것이다.

PHP 버전 5.3부터 늦은 정적 바인딩이 지원된다. 구체적으로, 위의 `self::$word`가 다음 블록처럼 `static::$word`로 바뀌었다면, `B::hello()`에 대한 호출의 결과는 "bye"가 된다.

```php
class A {
static $word = "hello";
static function hello() {print static::$word;}
}

class B extends A {
static $word = "bye";
}

B::hello();

3. 리바인딩과 변형 (Rebinding and Mutation)

리바인딩은 변형(mutation)과 혼동해서는 안 된다. "리바인딩"은 참조하는 식별자에 대한 변화이고, "변형"은 참조되는 값의 변화이다. 다음의 자바 코드를 보자:

```java
LinkedList list;
list = new LinkedList();
list.add("foo");
list = null;
```

식별자 `list`는 초기에 아무것도 참조하지 않다가(초기화되지 않음), 객체를 참조하기 위해 리바운드된다(링크드 리스트). `list`에 의해 참조되는 링크드 리스트는 리스트에 문자열을 추가하면서 변형된다. 마지막으로 `list`는 `null`에 리바운드된다.

재바인딩은 변이 또는 할당과 혼동해서는 안 된다.

* 재바인딩참조 식별자에 대한 변경이다.
* 할당은 (참조된) 변수에 대한 변경이다.
* 변이는 메모리 내의 객체에 대한 변경이며, 변수에 의해 참조되거나 식별자에 바인딩될 수 있다.

다음 자바 코드를 살펴보자.

```java
LinkedList list;
list = new LinkedList();
list.add("foo");
list = null;
{ LinkedList list = new LinkedList(); list.add(Integer(2)); }
```

식별자 `list`는 첫 번째 줄에서 변수에 바인딩된다. 두 번째 줄에서는 객체(문자열 연결 목록)가 변수에 할당된다. 그런 다음 변수가 참조하는 연결 목록이 변이되어 목록에 문자열이 추가된다. 다음으로, 변수에 상수 `null`이 할당된다. 마지막 줄에서 식별자는 블록 범위에 대해 재바인딩된다. 블록 내의 연산은 새 변수에 접근하며, 이전에 `list`에 바인딩된 변수에 접근하지 않는다.