อะไรคือความแตกต่างระหว่างผู้ประกอบการที่ได้รับมอบหมาย=
และ<-
ใน R?
ดังที่ตัวอย่างของคุณแสดง=
และ<-
มีลำดับความสำคัญของโอเปอเรเตอร์ที่แตกต่างกันเล็กน้อย (ซึ่งกำหนดลำดับของการประเมินเมื่อผสมในนิพจน์เดียวกัน) ในความเป็นจริง?Syntax
ใน R ให้ตารางตัวดำเนินการลำดับความสำคัญจากสูงสุดไปต่ำสุด:
…
‘-> ->>’ rightwards assignment
‘<- <<-’ assignment (right to left)
‘=’ assignment (right to left)
…
แต่นี่คือความแตกต่างเท่านั้น?
เนื่องจากคุณถูกถามเกี่ยวกับผู้ดำเนินการที่ได้รับมอบหมาย : ใช่นั่นคือความแตกต่างเท่านั้น อย่างไรก็ตามคุณจะได้รับการให้อภัยจากการเชื่อเป็นอย่างอื่น แม้แต่เอกสาร R ของการ?assignOps
อ้างสิทธิ์ว่ามีความแตกต่างมากขึ้น:
โอเปอเรเตอร์<-
สามารถใช้งานได้ทุกที่ในขณะที่โอเปอเรเตอร์=
ได้รับอนุญาตที่ระดับบนสุดเท่านั้น (เช่นในนิพจน์ทั้งหมดที่พิมพ์ที่คอมมานด์พรอมต์) หรือเป็นหนึ่งในนิพจน์ย่อยในรายการนิพจน์ที่ถูกโยง
ให้ไม่ใส่ดีจุดเกินไปในมันเอกสาร R คือ (อย่างละเอียด) ผิด [ 1 ] นี่เป็นเรื่องง่ายที่จะแสดง: เราเพียงแค่ต้องค้นหาตัวอย่างเคาน์เตอร์ของตัว=
ดำเนินการที่ไม่ใช่ (a) ที่ระดับสูงสุดและ (b) นิพจน์ย่อยในรายการของนิพจน์ (เช่น{…; …}
) - ไม่มีความกังวลใจเพิ่มเติม:
x
# Error: object 'x' not found
sum((x = 1), 2)
# [1] 3
x
# [1] 1
เห็นได้ชัดว่าเราได้ทำการมอบหมายใช้=
นอกบริบท (a) และ (b) เหตุใดเอกสารของคุณลักษณะแกนภาษา R จึงผิดมาหลายทศวรรษ
เป็นเพราะในไวยากรณ์ของ R สัญลักษณ์=
มีความหมายที่แตกต่างกันสองประการที่ทำให้เกิดความสับสนเป็นประจำ:
- ความหมายแรกคือในฐานะที่เป็นผู้ประกอบการที่ได้รับมอบหมาย นี่คือทั้งหมดที่เราพูดถึง
- ความหมายที่สองไม่ใช่โอเปอเรเตอร์ แต่เป็นโทเค็นของไวยากรณ์ที่ส่งสัญญาณการตั้งชื่ออาร์กิวเมนต์ที่ผ่านในการเรียกใช้ฟังก์ชัน ซึ่งแตกต่างจาก
=
ผู้ประกอบการที่ไม่ได้ดำเนินการที่รันไทม์มันเพียงเปลี่ยนวิธีการแยกวิเคราะห์การแสดงออก
มาดูกัน.
ในรหัสใด ๆ ของแบบฟอร์มทั่วไป ...
‹function_name›(‹argname› = ‹value›, …)
‹function_name›(‹args›, ‹argname› = ‹value›, …)
… =
เป็นโทเค็นที่กำหนดอาร์กิวเมนต์การส่งผ่านชื่อ: ไม่ใช่ตัวดำเนินการกำหนด นอกจากนี้ห้าม=
ทั้งหมดในบริบทของประโยค:
if (‹var› = ‹value›) …
while (‹var› = ‹value›) …
for (‹var› = ‹value› in ‹value2›) …
for (‹var1› in ‹var2› = ‹value›) …
สิ่งเหล่านี้จะทำให้เกิดข้อผิดพลาด“ ที่ไม่คาดคิด '=' เป็นใน
ในบริบทอื่นใด=
อ้างถึงการเรียกผู้ดำเนินการที่ได้รับมอบหมาย โดยเฉพาะอย่างยิ่งเพียงใส่วงเล็บรอบ subexpression ทำให้ใด ๆ ข้างต้น (ก) ที่ถูกต้องและ (ข) ได้รับมอบหมาย ตัวอย่างเช่นการดำเนินการต่อไปนี้ได้รับมอบหมาย:
median((x = 1 : 10))
แต่ยัง:
if (! (nf = length(from))) return()
ตอนนี้คุณอาจคัดค้านว่ารหัสนั้นเลวร้าย (และคุณอาจถูก) แต่ฉันเอาโค้ดนี้มาจากbase::file.copy
ฟังก์ชั่น (แทนที่<-
ด้วย=
) - มันเป็นรูปแบบที่แพร่หลายในฐาน code R ส่วนใหญ่
คำอธิบายต้นฉบับโดย John Chambersซึ่งเอกสาร R น่าจะอยู่บนพื้นฐานของความเป็นจริงอธิบายนี้อย่างถูกต้อง:
=
อนุญาตให้[ มอบหมาย] เพียงสองแห่งในไวยากรณ์: ที่ระดับบนสุด (เป็นโปรแกรมที่สมบูรณ์หรือการแสดงออกของผู้ใช้พิมพ์); และเมื่อแยกออกจากโครงสร้างโลจิคัลโดยรอบ, วงเล็บปีกกาหรือวงเล็บพิเศษ
คำสารภาพ: ฉันโกหกก่อนหน้านี้ มีเป็นหนึ่งความแตกต่างระหว่างเพิ่มเติม=
และ<-
ผู้ประกอบการ: พวกเขาเรียกฟังก์ชั่นที่แตกต่างกัน โดยค่าเริ่มต้นฟังก์ชั่นเหล่านี้จะทำสิ่งเดียวกัน แต่คุณสามารถแทนที่หนึ่งในนั้นแยกกันเพื่อเปลี่ยนพฤติกรรม ในทางตรงกันข้าม<-
และ->
(จากซ้ายไปขวา) ถึงแม้ว่าจะมีความแตกต่างทางวากยสัมพันธ์มักเรียกฟังก์ชั่นเดียวกันเสมอ การเอาชนะอย่างใดอย่างหนึ่งยังแทนที่อีกด้วย รู้นี้เป็นจริงไม่ค่อยแต่ก็สามารถนำมาใช้สำหรับบางแง่สนุก
<-
สัญลักษณ์มาจากคีย์บอร์ด APL รุ่นเก่าที่มี<-
ปุ่มเดียว