我试图更好地了解closures,尤其是有关函数的作用域以及如何使用其封闭环境的详细信息>
基于Description
帮助页面的rlang::fn_env()
部分,我了解到,一个函数始终可以访问其范围内的所有变量,并且其封闭环境属于该范围。
但是,为什么不能“在事实发生之后”(即在函数创建之后)操作闭包环境的内容呢?
通过R的词法作用域,当我将bar()
放入其封闭环境中时,x
是否应该找不到foo <- function(fun) {
env_closure <- rlang::fn_env(fun)
env_closure$x <- 5
fun()
}
bar <- function(x) x
foo(bar)
#> Error in fun(): argument "x" is missing, with no default
?
class AppDelegate: NSObject, NSApplicationDelegate, CLLocationManagerDelegate {
let locationManager = CLLocationManager()
func applicationDidFinishLaunching(_ aNotification: Notification) {
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyBest
}
func scanLocationRequest{
locationManager.startUpdatingLocation()
// Call this when a notification receives.
}
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
let currentLocation = locations.last
locationManager.stopUpdatingLocation()
sendLocationReport(currentLocation: currentLocation!)
}
}
答案 0 :(得分:0)
啊,我想我现在明白了。
它与函数形式参数的结构有关:
如果定义的参数没有默认值,则R在调用该函数时会抱怨而未指定,即使从技术上讲它可以在其范围内查找它。
即使您不想定义默认值,启动词法作用域的一种方法是在运行时通过rlang::fn_fmls()
设置默认值。
foo <- function(fun) {
env_enclosing <- rlang::fn_env(fun)
env_enclosing$x <- 5
fun()
}
# No argument at all -> lexical scoping takes over
baz <- function() x
foo(baz)
#> [1] 5
# Set defaults to desired values on the fly at run time of `foo()`
foo <- function(fun) {
env_enclosing <- rlang::fn_env(fun)
env_enclosing$x <- 5
fmls <- rlang::fn_fmls(fun)
fmls$x <- substitute(get("x", envir = env_enclosing, inherits = FALSE))
rlang::fn_fmls(fun) <- fmls
fun()
}
bar <- function(x) x
foo(bar)
#> [1] 5
答案 1 :(得分:0)
由于我不熟悉rlang
库,因此我无法真正遵循您的示例,但是我认为R中闭包的一个好例子是:
bucket <- function() {
n <- 1
foo <- function(x) {
assign("n", n+1, envir = parent.env(environment()))
n
}
foo
}
bar <- bucket()
由于bar()
是在bucket
的函数环境中定义的,因此其父环境是bucket
,因此您可以在其中携带一些数据。每次运行时,您都会修改bucket
环境:
bar()
[1] 2
bar()
[1] 3
bar()
[1] 4