编程中的闭包。
闭包是一个函数,即使在外部函数完成执行后,它仍保留对其词法作用域变量的访问权限。 这在编程中是一个强大的概念,特别是在支持函数式编程的语言中。
在Julia的示例中,我们看到了一个经典的闭包实现。:
In [ ]:
function make_counter()
count = 0 # Эта переменная «замыкается» внутри функции
function counter()
count += 1
return count
end
return counter
end
Out[0]:
这里 **make_counter**是创建并返回函数的工厂函数 counter. 内部功能 **counter**可以访问变量 **count**即使之后 **make_counter**完成其执行。
短路如何工作
-
变量捕获:当创建闭包时,它会"记住"其周围作用域中的所有变量。
-
State:这些变量在闭包调用之间保留其状态。
-
隔离:每个新闭包都会创建自己的捕获变量副本。
在我们的例子中,每个调用都是 **make_counter()**使用自己的变量创建一个新的闭包 count:
In [ ]:
my_counter = make_counter() # Создаем первое замыкание
println("my_counter: $my_counter")
another_counter = make_counter() # Создаем второе независимое замыкание
println("another_counter: $another_counter")
要使用它,调用创建的计数器就足够了。
In [ ]:
println("my_counter первый вызов: $(my_counter())")
println("my_counter второй вызов: $(my_counter())")
println("Вызов another_counter: $(another_counter())")
闭包的实际应用是,例如,私有变量的实现。
In [ ]:
function create_person(name)
age = 0
function get_name()
return name
end
function get_age()
return age
end
function have_birthday()
age += 1
return age
end
return (get_name=get_name, get_age=get_age, have_birthday=have_birthday)
end
person = create_person("Alice")
println(person.get_name()) # Alice
println(person.have_birthday()) # 1
或memoization(结果缓存)
In [ ]:
function make_cached(f)
cache = Dict()
function cached(x)
if !haskey(cache, x)
cache[x] = f(x)
end
return cache[x]
end
return cached
end
# Пример использования
expensive_computation(x) = (sleep(1); x^2)
cached_comp = make_cached(expensive_computation)
println(cached_comp(2)) # Вычисляется (занимает время)
println(cached_comp(2)) # Берется из кеша (мгновенно)
还可以创建具有预设参数的函数。
In [ ]:
function make_multiplier(factor)
function multiplier(x)
return x * factor
end
return multiplier
end
double = make_multiplier(2)
triple = make_multiplier(3)
println(double(5)) # 10
println(triple(5)) # 15
结论
总而言之,值得分析这种方法的利弊。
优势:
*封装和数据隐藏,
*创建有状态函数,
*创建专门功能的灵活性,
*支持函数式编程模式。
缺点:
*内存消耗(捕获的变量不释放),
*调试可能遇到的困难
最后,我想说闭包是一个强大的工具。 它们用于许多领域,从简单的计数器到复杂设计模式的实现。 理解闭包对于任何使用支持功能的语言的开发人员来说都很重要。
所给出的例子只展示了闭包的一小部分可能性。 通过对它们进行试验,您将能够找到越来越多的新方法来将此概念应用到您的项目中。