ขอบเขตส่วนกลางเทียบกับขอบเขตเฉพาะที่
แยกความแตกต่างระหว่าง .GlobalEnv, environment ของฟังก์ชัน และคลอสเชอร์
ขอบเขตส่วนกลางเทียบกับขอบเขตเฉพาะที่ เป็นบทเรียน R Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 3 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน R Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส R Academy มีบทเรียนทั้งหมด 4 บทเรียน
ตัวแปรเฉพาะที่ในฟังก์ชัน
ตัวแปรที่กำหนดด้วย <- หรือ = ภายในส่วนเนื้อหาของฟังก์ชันจะเป็นตัวแปรเฉพาะที่ของฟังก์ชันนั้น ตัวแปรเหล่านี้ถูกสร้างในสภาพแวดล้อมของฟังก์ชันเองและหายไปเมื่อฟังก์ชันส่งคืนค่า โดยจะไม่ส่งผลต่อขอบเขตของผู้เรียกใช้
x <- 'global'
f <- function() {
x <- 'local' # creates a new local binding, does not modify global x
cat('Inside f: x =', x, '\n')
}
f()
cat('Outside f: x =', x, '\n') # still 'global'พารามิเตอร์ฟังก์ชันเป็นตัวแปรเฉพาะที่
พารามิเตอร์ฟังก์ชันก็เป็นตัวแปรเฉพาะที่เช่นกัน การแก้ไขพารามิเตอร์ภายในฟังก์ชันจะไม่ส่งผลต่ออาร์กิวเมนต์ในสภาพแวดล้อมของผู้เรียกใช้ R ส่งอาร์กิวเมนต์ด้วยค่า (โดยมีการคัดลอกเมื่อแก้ไข)
double_it <- function(n) {
n <- n * 2 # modifies local copy only
cat('Inside:', n, '\n')
}
my_n <- 5
double_it(my_n)
cat('Outside:', my_n, '\n') # still 5<<- สำหรับการกำหนดค่าในส่วนกลาง
<<- (การกำหนดค่าเหนือสภาพแวดล้อม) จะค้นหาขึ้นไปตามสายโซ่สภาพแวดล้อมแม่ และกำหนดค่าให้กับการจับคู่แรกที่พบ หากไม่พบการจับคู่ที่ใดเลย จะสร้างการผูกชื่อในสภาพแวดล้อมส่วนกลาง ควรใช้เท่าที่จำเป็น เพราะการใช้ <<- มากเกินไปทำให้เข้าใจการทำงานของฟังก์ชันได้ยาก
total <- 0
add_to_total <- function(x) {
total <<- total + x
}
add_to_total(10)
add_to_total(25)
add_to_total(5)
cat('Total:', total, '\n')<<- ค้นหาขึ้นไปตามสายโซ่
<<- ไม่ได้กำหนดค่าให้กับสภาพแวดล้อมส่วนกลางโดยทันที แต่จะไล่ขึ้นไปตามสายโซ่สภาพแวดล้อมแม่ และกำหนดค่าให้กับสภาพแวดล้อมแรกที่มีชื่อนั้นอยู่ หากตัวแปรมีอยู่ในฟังก์ชันที่ครอบอยู่ ตัวแปรในฟังก์ชันนั้นจะถูกอัปเดต
outer <- function() {
n <- 0
increment <- function() n <<- n + 1
increment()
increment()
cat('n in outer:', n, '\n') # n was in outer's env, updated there
}
outer()
# n does NOT appear in global env
cat('n in global:', exists('n', envir = globalenv()), '\n')assign() สำหรับระบุสภาพแวดล้อมเป้าหมายอย่างชัดเจน
assign('name', value, envir = e) กำหนดค่าให้กับสภาพแวดล้อมที่ระบุโดยตรง ชัดเจนกว่า <<- และมีประโยชน์เมื่อคุณมีออบเจ็กต์สภาพแวดล้อมและต้องการกำหนดค่าให้ตำแหน่งนั้นโดยเฉพาะ
my_env <- new.env(parent = emptyenv())
assign('score', 95, envir = my_env)
assign('name', 'Alice', envir = my_env)
cat('score:', get('score', envir = my_env), '\n')
cat('name :', get('name', envir = my_env), '\n')local() — บล็อกโค้ดที่แยกออกจากกัน
local({...}) ประเมินนิพจน์ในสภาพแวดล้อมเฉพาะที่ใหม่ ตัวแปรที่สร้างภายในบล็อกจะไม่รั่วไหลไปยังสภาพแวดล้อมส่วนกลาง เหมาะสำหรับการคำนวณชั่วคราวที่ไม่ควรทำให้พื้นที่ทำงานปะปน
result <- local({
temp1 <- 100
temp2 <- 200
temp1 + temp2 # the last expression is returned
})
cat('result:', result, '\n')
cat('temp1 in global:', exists('temp1'), '\n') # FALSElocal() กับฟังก์ชันสำหรับการแยกขอบเขต
ทั้ง local() และฟังก์ชันที่ถูกเรียกใช้ทันทีช่วยแยกขอบเขตได้ local() กระชับกว่าเมื่อใช้แยกขอบเขตเพียงครั้งเดียว ส่วนฟังก์ชันที่ตั้งชื่อเหมาะกว่าเมื่อคุณต้องการนำตรรกะกลับมาใช้ซ้ำหรือนำไปทดสอบ
# Option A: local()
result_a <- local({
x <- 7
y <- 3
x * y
})
# Option B: immediately invoked function
result_b <- (function() {
x <- 7
y <- 3
x * y
})()
cat(result_a, result_b, '\n')
cat('x in global:', exists('x'), '\n')การอ่านตัวแปรส่วนกลางจากฟังก์ชัน
ฟังก์ชันสามารถอ่านตัวแปรจากขอบเขตที่ครอบอยู่ (ไม่ว่าจะเป็นส่วนกลางหรือขอบเขตอื่น) ได้โดยไม่ต้องใช้รูปแบบพิเศษ นี่เป็นการกำหนดขอบเขตแบบเลกซิคัลตามปกติ อย่างไรก็ตาม การพึ่งพาสถานะส่วนกลางมากเกินไปทำให้ทดสอบฟังก์ชันได้ยาก จึงควรใช้อาร์กิวเมนต์ที่ระบุอย่างชัดเจนเมื่อทำได้
tax_rate <- 0.20 # global configuration
apply_tax <- function(price) {
price * (1 + tax_rate) # reads tax_rate from global
}
cat(apply_tax(100), '\n')
cat(apply_tax(250), '\n')การบดบังชื่อตัวแปร
เมื่อตัวแปรเฉพาะที่มีชื่อเดียวกับตัวแปรส่วนกลาง การผูกชื่อเฉพาะที่จะบดบังตัวแปรส่วนกลาง ภายในฟังก์ชันจะใช้ตัวแปรเฉพาะที่ ส่วนกลางจะไม่ถูกเปลี่ยนแปลง หากเกิดขึ้นโดยไม่ตั้งใจ อาจทำให้เกิดข้อผิดพลาดที่สังเกตได้ยาก
mean <- 99 # shadows base R's mean() function
cat(mean, '\n') # prints 99, not the function
# To call the real mean, use base:: prefix
cat(base::mean(c(1, 2, 3, 4, 5)), '\n')
rm(mean) # remove the shadowสภาพแวดล้อมของ function()
ทุกครั้งที่เรียกใช้ฟังก์ชัน R จะสร้างสภาพแวดล้อมใหม่สำหรับการเรียกใช้นั้น โดยมีสภาพแวดล้อมที่ครอบอยู่ของฟังก์ชันเป็นสภาพแวดล้อมแม่ ตัวแปรเฉพาะที่จากการเรียกใช้แต่ละครั้งจะไม่รบกวนกัน แม้เป็นการเรียกใช้แบบเวียนเกิด
factorial_r <- function(n) {
# Each recursive call has its own local n
if (n <= 1) return(1)
n * factorial_r(n - 1)
}
cat('5! =', factorial_r(5), '\n')
cat('7! =', factorial_r(7), '\n')rm() สำหรับลบตัวแปร
rm('name') หรือ rm(name) ลบการผูกชื่อออกจากสภาพแวดล้อมปัจจุบัน (หรือสภาพแวดล้อมที่ระบุ) ใช้สำหรับล้างตัวแปรชั่วคราว ส่ง envir = e เพื่อลบออกจากสภาพแวดล้อมที่กำหนด
x <- 42
y <- 'hello'
cat('Before rm:', ls(), '\n')
rm(x)
cat('After rm(x):', exists('x'), '\n')
rm('y')
cat('After rm(y):', exists('y'), '\n')ตรวจสอบความเข้าใจอย่างรวดเร็ว
<<- ทำสิ่งใดที่ <- แบบปกติทำไม่ได้
ขอบเขต: ประเด็นสำคัญ
ประเด็นสำคัญเกี่ยวกับขอบเขตส่วนกลางกับขอบเขตเฉพาะที่:
<-ภายในฟังก์ชันสร้างตัวแปรเฉพาะที่ ตัวแปรส่วนกลางจะไม่เปลี่ยนแปลง- พารามิเตอร์ฟังก์ชันเป็นตัวแปรเฉพาะที่ R ส่งค่าด้วยค่า (มีการคัดลอกเมื่อแก้ไข)
<<-ไล่ขึ้นไปตามสายโซ่สภาพแวดล้อมแม่และแก้ไขการผูกชื่อแรกที่ตรงกันassign('x', val, envir=e)ใช้กำหนดค่าโดยระบุสภาพแวดล้อมเป้าหมายอย่างชัดเจนlocal({...})ให้ขอบเขตชั่วคราวโดยไม่ต้องสร้างฟังก์ชันที่มีชื่อ- หลีกเลี่ยงการบดบังชื่อสำคัญ (เช่น
mean,c,T)
# Demonstrate local + <<- cleanly
running_sum <- 0
local({
values <- c(10, 20, 30, 40)
for (v in values) running_sum <<- running_sum + v
})
cat('Running sum:', running_sum, '\n')
cat('values in global:', exists('values'), '\n')คำถามที่พบบ่อย
บทเรียน “ขอบเขตส่วนกลางเทียบกับขอบเขตเฉพาะที่” ฟรีหรือไม่
ใช่ — ข้อความเต็มของ “ขอบเขตส่วนกลางเทียบกับขอบเขตเฉพาะที่” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส R Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส R Academy มีบทเรียนทั้งหมด 4 บทเรียน
คุณจะเรียนรู้อะไรในบทเรียน “ขอบเขตส่วนกลางเทียบกับขอบเขตเฉพาะที่”
แยกความแตกต่างระหว่าง .GlobalEnv, environment ของฟังก์ชัน และคลอสเชอร์ คุณปฏิบัติ R Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน
คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน R Academy หรือไม่
ไม่จำเป็นต้องมีประสบการณ์มาก่อน R Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 3 จากทั้งหมด 4 บทเรียน
บทเรียน “ขอบเขตส่วนกลางเทียบกับขอบเขตเฉพาะที่” ใช้เวลานานแค่ไหน
บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย
ฉันเขียนและรันโค้ดในบทเรียน R Academy นี้ได้ไหม
ได้ บทเรียน R Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ
บทเรียนทั้งหมดในหลักสูตรนี้
- Environment ใน R คืออะไร
- กฎขอบเขตแบบเล็กซิคัล
- ขอบเขตส่วนกลางเทียบกับขอบเขตเฉพาะที่
- การสร้างและตรวจสอบ Environment