컴퓨터 언어에서 클로저(Closure)는 일급 객체 함수(first-class functions)의 개념을 이용하여 스코프(scope)에 묶인 변수를 바인딩 하기 위한 일종의 기술이다. 기능상으로, 클로저는 함수를 저장한 레코드(record)이며, 스코프(scope)의 인수(Factor)들은 클로저가 만들어질 때 정의(define)되며, 스코프 내의 영역이 소멸(remove)되었어도 그에 대한 접근(access)은 독립된 복사본인 클로저를 통해 이루어질 수 있다.
def greet(name):
# inner function
def display_name():
print("Hi", name)
# call inner function
return display_name
# call outer function
c = greet("John")
c()
# Output: Hi John
러스트의 클로저는 다른 언어에서의 클로저와 어떤 점에서 다른가?
struct City { name: String,
population: i64, country: String, ...
}
fn sort_cities(cities: &mut Vec<City>)
{cities.sort(); // error: how do you want them sorted?}
/// Helper function for sorting cities by population.
fn city_population_descending(city: &City) -> i64
{ -city.population}
fn sort_cities(cities: &mut Vec<City>)
{ cities.sort_by_key(city_population_descending); // ok}
fn sort_cities(cities: &mut Vec<City>)
{ cities.sort_by_key(|city| -city.population);}
// Start an animation that rearranges the rows in a table of cities.
function startSortingAnimation(cities, stat) {
// Helper function that we'll use to sort the table. // Note that this function refers to stat.
function keyfn(city) {
return city.get_statistic(stat); }
if (pendingSort)
pendingSort.cancel();
// Now kick off an animation, passing keyfn to it.
// The sorting algorithm will call keyfn later.
endingSort = new SortingAnimation(cities, keyfn);
}
자바스크립트 에서는 … 클로저 keyfn
은 SortingAnimation
오브젝트에 저장되며, 아마 startSortingAnimation이 반환된 이후에 호출될 것이다. 함수가 반환되면 그 모든 변수들과 인수들은 스코프밖을 벗어나서 버려진다. 하지만 여기에서, 자바스크립트 엔진은 stat을 어떻게든 유지하기 위해 힙에 할당하고 가비지컬렉터가 나중에 이를 회수하게 한다.
하지만 가비지컬렉터가 없는 러스트에서는 이를 어떻게 해결할까?