R语言闭包 #

一、闭包概述 #

闭包是一个函数及其相关环境的组合,可以访问定义时的外部变量。

二、闭包基础 #

2.1 创建闭包 #

r
make_adder <- function(x) {
  function(y) {
    x + y
  }
}

add5 <- make_adder(5)
add10 <- make_adder(10)

add5(3)
add10(3)

2.2 访问外部变量 #

r
make_multiplier <- function(factor) {
  function(x) {
    x * factor
  }
}

double <- make_multiplier(2)
triple <- make_multiplier(3)

double(5)
triple(5)

三、状态管理 #

3.1 计数器 #

r
make_counter <- function() {
  count <- 0
  
  function() {
    count <<- count + 1
    count
  }
}

counter <- make_counter()
counter()
counter()
counter()

3.2 多方法闭包 #

r
make_counter <- function() {
  count <- 0
  
  list(
    increment = function() {
      count <<- count + 1
      count
    },
    decrement = function() {
      count <<- count - 1
      count
    },
    get = function() count,
    reset = function() {
      count <<- 0
      count
    }
  )
}

counter <- make_counter()
counter$increment()
counter$increment()
counter$get()
counter$reset()

3.3 银行账户 #

r
make_account <- function(initial_balance) {
  balance <- initial_balance
  
  list(
    deposit = function(amount) {
      balance <<- balance + amount
      balance
    },
    withdraw = function(amount) {
      if (amount > balance) {
        stop("余额不足")
      }
      balance <<- balance - amount
      balance
    },
    get_balance = function() balance
  )
}

account <- make_account(100)
account$deposit(50)
account$withdraw(30)
account$get_balance()

四、函数工厂 #

4.1 创建系列函数 #

r
power_factory <- function(n) {
  function(x) {
    x ^ n
  }
}

square <- power_factory(2)
cube <- power_factory(3)

square(5)
cube(5)

4.2 配置函数 #

r
make_logger <- function(prefix) {
  function(message) {
    cat(prefix, message, "\n")
  }
}

info_log <- make_logger("[INFO]")
error_log <- make_logger("[ERROR]")

info_log("程序启动")
error_log("发生错误")

4.3 验证函数工厂 #

r
make_validator <- function(min_val, max_val) {
  function(x) {
    x >= min_val && x <= max_val
  }
}

validate_age <- make_validator(0, 120)
validate_score <- make_validator(0, 100)

validate_age(25)
validate_age(150)
validate_score(85)

五、缓存与记忆化 #

5.1 简单缓存 #

r
make_cached <- function(f) {
  cache <- new.env()
  
  function(x) {
    key <- as.character(x)
    
    if (exists(key, envir = cache)) {
      return(get(key, envir = cache))
    }
    
    result <- f(x)
    assign(key, result, envir = cache)
    result
  }
}

slow_fib <- function(n) {
  if (n <= 1) return(n)
  slow_fib(n - 1) + slow_fib(n - 2)
}

fib <- make_cached(function(n) {
  if (n <= 1) return(n)
  fib(n - 1) + fib(n - 2)
})

system.time(fib(30))
system.time(fib(30))

5.2 通用记忆化 #

r
memoize <- function(f) {
  cache <- new.env()
  
  function(...) {
    args <- list(...)
    key <- digest::digest(args)
    
    if (exists(key, envir = cache)) {
      return(get(key, envir = cache))
    }
    
    result <- f(...)
    assign(key, result, envir = cache)
    result
  }
}

六、配置管理 #

6.1 设置管理器 #

r
make_settings <- function() {
  settings <- list()
  
  list(
    set = function(key, value) {
      settings[[key]] <<- value
      invisible(value)
    },
    get = function(key, default = NULL) {
      if (key %in% names(settings)) {
        settings[[key]]
      } else {
        default
      }
    },
    remove = function(key) {
      settings[[key]] <<- NULL
      invisible(NULL)
    },
    list_all = function() {
      settings
    }
  )
}

config <- make_settings()
config$set("host", "localhost")
config$set("port", 8080)
config$get("host")
config$list_all()

6.2 数据库连接管理 #

r
make_db_manager <- function(connection_string) {
  connected <- FALSE
  
  list(
    connect = function() {
      if (connected) {
        warning("已经连接")
        return(invisible(NULL))
      }
      connected <<- TRUE
      cat("连接到:", connection_string, "\n")
    },
    disconnect = function() {
      if (!connected) {
        warning("未连接")
        return(invisible(NULL))
      }
      connected <<- FALSE
      cat("已断开连接\n")
    },
    is_connected = function() connected
  )
}

db <- make_db_manager("mysql://localhost/mydb")
db$is_connected()
db$connect()
db$is_connected()
db$disconnect()

七、实践示例 #

7.1 事件发射器 #

r
make_emitter <- function() {
  listeners <- list()
  id <- 0
  
  list(
    on = function(event, callback) {
      id <<- id + 1
      listeners[[as.character(id)]] <<- list(event = event, callback = callback)
      id
    },
    off = function(listener_id) {
      listeners[[as.character(listener_id)]] <<- NULL
    },
    emit = function(event, ...) {
      for (l in listeners) {
        if (l$event == event) {
          l$callback(...)
        }
      }
    }
  )
}

emitter <- make_emitter()
emitter$on("data", function(x) cat("收到数据:", x, "\n"))
emitter$emit("data", "Hello")

7.2 限流器 #

r
make_rate_limiter <- function(limit, window) {
  timestamps <- c()
  
  function() {
    now <- Sys.time()
    timestamps <<- timestamps[timestamps > now - window]
    
    if (length(timestamps) < limit) {
      timestamps <<- c(timestamps, now)
      TRUE
    } else {
      FALSE
    }
  }
}

limiter <- make_rate_limiter(3, 10)
limiter()
limiter()
limiter()
limiter()

八、总结 #

本章学习了:

  • 闭包的基本概念
  • 状态管理实现
  • 函数工厂模式
  • 缓存与记忆化
  • 配置管理
  • 实际应用示例

闭包是R语言高级编程的重要工具,可以实现复杂的状态管理!

最后更新:2026-03-27