<- không phân công trong môi trường hiện tại.
Khi bạn ở trong hàm R sẽ tạo một môi trường mới cho bạn. Theo mặc định, nó bao gồm mọi thứ từ môi trường mà nó được tạo để bạn có thể sử dụng các biến đó nhưng mọi thứ mới bạn tạo sẽ không được ghi vào môi trường toàn cầu.
Trong hầu hết các trường hợp <<-sẽ gán cho các biến đã có trong môi trường toàn cầu hoặc tạo một biến trong môi trường toàn cầu ngay cả khi bạn đang ở trong một hàm. Tuy nhiên, nó không hoàn toàn đơn giản như vậy. Những gì nó làm là kiểm tra môi trường cha cho một biến có tên quan tâm. Nếu nó không tìm thấy nó trong môi trường cha mẹ của bạn, nó sẽ chuyển đến cha mẹ của môi trường cha mẹ (tại thời điểm hàm được tạo) và nhìn vào đó. Nó tiếp tục hướng lên môi trường toàn cầu và nếu không tìm thấy trong môi trường toàn cầu, nó sẽ gán biến trong môi trường toàn cầu.
Điều này có thể minh họa những gì đang xảy ra.
bar <- "global"
foo <- function(){
bar <- "in foo"
baz <- function(){
bar <- "in baz - before <<-"
bar <<- "in baz - after <<-"
print(bar)
}
print(bar)
baz()
print(bar)
}
> bar
[1] "global"
> foo()
[1] "in foo"
[1] "in baz - before <<-"
[1] "in baz - after <<-"
> bar
[1] "global"
Lần đầu tiên chúng tôi in thanh mà chúng tôi chưa gọi foonên nó vẫn mang tính toàn cầu - điều này có ý nghĩa. Lần thứ hai chúng tôi in nó bên trong footrước khi gọi bazđể giá trị "trong foo" có ý nghĩa. Sau đây là nơi chúng ta thấy những gì <<-đang thực sự làm. Giá trị tiếp theo được in là "in baz - before << -" mặc dù câu lệnh in xuất hiện sau <<-. Điều này là do <<-không nhìn vào môi trường hiện tại (trừ khi bạn ở trong môi trường toàn cầu trong trường hợp đó <<-hoạt động như thế nào <-). Vì vậy, bên trong bazgiá trị của thanh vẫn là "in baz - trước << -". Khi chúng ta gọi bazbản sao của thanh bên trong foođược thay đổi thành "in baz" nhưng như chúng ta có thể thấy toàn cầu barlà không thay đổi.barđược định nghĩa bên trong foolà trong môi trường phụ huynh khi chúng tôi tạo ra bazvì vậy đây là bản sao đầu tiên của barmà <<-nhìn thấy và do đó sao chép nó gán cho. Vì vậy, <<-không chỉ trực tiếp giao cho môi trường toàn cầu.
<<-là khó khăn và tôi không khuyên bạn nên sử dụng nó nếu bạn có thể tránh nó. Nếu bạn thực sự muốn gán cho môi trường toàn cầu, bạn có thể sử dụng hàm gán và nói rõ rằng bạn muốn gán toàn cục.
Bây giờ tôi thay đổi <<-câu lệnh gán và chúng ta có thể thấy tác dụng nào có:
bar <- "global"
foo <- function(){
bar <- "in foo"
baz <- function(){
assign("bar", "in baz", envir = .GlobalEnv)
}
print(bar)
baz()
print(bar)
}
bar
#[1] "global"
foo()
#[1] "in foo"
#[1] "in foo"
bar
#[1] "in baz"
Vì vậy, cả hai lần chúng tôi in thanh bên trong foogiá trị là "trong foo" ngay cả sau khi gọi baz. Điều này là do assignthậm chí không bao giờ xem xét bản sao barbên trong của foo bởi vì chúng tôi đã nói với nó chính xác nơi để tìm. Tuy nhiên, lần này giá trị của thanh trong môi trường toàn cầu đã thay đổi vì chúng tôi được chỉ định rõ ràng ở đó.
Bây giờ bạn cũng đã hỏi về việc tạo các biến cục bộ và bạn có thể thực hiện điều đó khá dễ dàng mà không cần tạo hàm ... Chúng ta chỉ cần sử dụng localhàm.
bar <- "global"
# local will create a new environment for us to play in
local({
bar <- "local"
print(bar)
})
#[1] "local"
bar
#[1] "global"
globalenv(); globalenv() %>% parent.env; globalenv() %>% parent.env %>% parent.env...