全局变量与工作空间

在所有函数外面(如R命令行)定义的变量是全局变量。 在命令行定义的所有变量都保存在工作空间 (workspace), 也称为全局环境中。

在RStudio的Environment窗格可以看到“Global Environment”的内容, 分为数据框(Data)其它变量(Values)函数(Functions)三类。

在命令行可以用ls()查看工作空间内容。

  1. > ls()
  2. [1] "a" "fib1" "fib2" "g" "gv" "i" "my_f" "tmp"

ls() 函数还支持正则匹配,我们可以使用pattern 参数匹配指定的变量。

此外,object.size 函数可以用来计算变量所占的存储大小,其也可以接受多个变量,计算其大小总和:

  1. > object.size(ls())
  2. 560 bytes

局部变量

在一般计算机语言中, “变量”实际是计算机内存中的一段存储空间, 但是R中略微复杂一些, R的变量实际是指向R对象的引用, 称为“绑定” (这点和py 类似?)。 在较简单的函数定义中大体上可以将R 变量看成是对应的存储空间。

函数的参数(自变量)在定义时并没有对应的存储空间, 所以也称函数定义中的参数为“形式参数”。

函数的形式参数在调用时被赋值为实参值(这是一般情形), 形参变量和函数体内被赋值的变量都是局部的。 这一点符合函数式编程(functional programming)的要求。所谓局部变量, 就是仅在函数运行时才存在, 一旦退出函数就不存在的变量。

  1. tmp = function(){b = 10; print(b)}
  2. > b
  3. 错误: 找不到对象'b'

在函数调用时,行参被赋值为实参,在函数内部对形式参数作任何修改在函数运行完成后都不影响原来的实参变量, 而且函数运行完毕后形式参数不再与实际的存储空间联系。

  1. a = 5
  2. > tmp = function(){a = 10; print(a)}
  3. > tmp()
  4. [1] 10
  5. > a
  6. [1] 5

如果我们希望在函数内对变量进行修改,可以将其返回值进行赋值。

  1. f <- function(x, inc=1){
  2. x <- x + inc
  3. x
  4. }

这里还有一个方法,即使用超赋值 <<-,可以将当前作用域的结果作用到上一级环境中,但需要谨慎使用。

函数内部可以读取全局变量的值,但一般不能修改全局变量的值。 在现代编程指导思想中, 全局变量容易造成不易察觉的错误, 应谨慎使用, 当然,也不是禁止使用, 有些应用中不使用全局变量会使得程序更复杂且低效。