ฉันเจอรหัสทับทิมสายนี้ สิ่งนี้&.
หมายความว่าอย่างไร
@object&.method
ฉันเจอรหัสทับทิมสายนี้ สิ่งนี้&.
หมายความว่าอย่างไร
@object&.method
คำตอบ:
มันเรียกว่าผู้ประกอบการนำทางที่ปลอดภัย นำมาใช้ในทับทิม 2.3.0 จะช่วยให้คุณเรียกวิธีการบนวัตถุโดยไม่ต้องกังวลว่าวัตถุที่อาจจะnil
(หลีกเลี่ยงundefined method for nil:NilClass
ข้อผิดพลาด) คล้ายกับวิธีการในทางรถไฟtry
ดังนั้นคุณสามารถเขียน
@person&.spouse&.name
แทน
@person.spouse.name if @person && @person.spouse
จากเอกสาร :
my_object.my_method
สิ่งนี้จะส่งข้อความ my_method ไปยัง my_object วัตถุใด ๆ ที่สามารถรับ แต่ขึ้นอยู่กับการมองเห็นวิธีการส่งข้อความอาจเพิ่ม NoMethodError
คุณสามารถใช้ &. ในการกำหนดตัวรับสัญญาณ my_method จะไม่ถูกเรียกใช้และผลลัพธ์จะเป็นศูนย์เมื่อตัวรับเป็นศูนย์ ในกรณีนั้นข้อโต้แย้งของ my_method จะไม่ได้รับการประเมิน
หมายเหตุ: แม้ว่า @Santosh จะให้คำตอบที่ชัดเจนและครบถ้วน แต่ฉันต้องการเพิ่มพื้นหลังเพิ่มเติมและเพิ่มบันทึกย่อที่สำคัญเกี่ยวกับการใช้กับตัวแปรที่ไม่ใช่อินสแตนซ์
มันถูกเรียกว่า "ตัวดำเนินการนำทางที่ปลอดภัย " ( aka "ตัวดำเนินการผูกมัดตัวเลือก", "ตัวดำเนินการ Null แบบมีเงื่อนไข" ฯลฯ ) Matz ดูเหมือนจะเรียกมันว่า "ผู้ดำเนินการที่อ้างว้าง" มันถูกนำมาใช้ในทับทิม 2.3 nil
มันจะส่งวิธีการเพื่อให้วัตถุเท่านั้นถ้ามันไม่ได้
# Call method `.profile` on `user` only if `user` is not `nil`
@user&.profile
# Equivalent to
unless @user.nil?
@user.profile
end
โปรดทราบว่ารหัสข้างต้นใช้ตัวแปรอินสแตนซ์ ถ้าคุณต้องการใช้โอเปอเรเตอร์ที่ปลอดภัยพร้อมตัวแปรโลคอลคุณจะต้องตรวจสอบว่าตัวแปรโลคอลของคุณถูกกำหนดไว้ก่อน
# `user` local variable is not defined previous
user&.profile
# This code would throw the following error:
NameError: undefined local variable or method `user' for main:Object
ในการแก้ไขปัญหานี้ให้ตรวจสอบว่าตัวแปรโลคัลของคุณถูกกำหนดไว้ก่อนหรือตั้งเป็นไม่มี:
# Option 1: Check the variable is defined
if defined?(user)
user&.profile
end
# Option 2: Define your local variable. Example, set it to nil
user = nil
user&.profile # Works and does not throw any errors
Rails มีtry
วิธีการที่เหมือนกันโดยทั่วไป มันใช้send
วิธีการภายในเพื่อเรียกวิธีการภายใน Matz แนะนำว่ามันช้าและควรเป็นคุณสมบัติภาษาในตัว
ภาษาการเขียนโปรแกรมอื่น ๆ อีกมากมายมีคุณสมบัติที่คล้ายกัน: Objective C, Swift, Python, Scala, CoffeeScript ฯลฯ อย่างไรก็ตามไวยากรณ์ทั่วไปคือ?.
(question dot) แต่ไวยากรณ์นี้ไม่สามารถนำมาใช้โดย Ruby เนื่องจาก?
ได้รับอนุญาตในชื่อเมธอดดังนั้น?.
ลำดับสัญลักษณ์จึงเป็นรหัสทับทิมที่ถูกต้อง ตัวอย่างเช่น:
2.even?.class # => TrueClass
นั่นเป็นสาเหตุที่ชุมชน Ruby ต้องมีไวยากรณ์ที่แตกต่างกัน มันได้รับการอภิปรายที่ใช้งานและตัวเลือกที่แตกต่างกันได้รับการพิจารณา ( .?
, ?
, &&
ฯลฯ ) นี่คือรายการของข้อควรพิจารณาบางอย่าง:
u.?profile.?thumbnails
u\profile\thumbnails
u!profile!thumbnails
u ? .profile ? .thumbnails
u && .profile && .thumbnails
# And finally
u&.profile&.thumbnails
ในขณะที่เลือกไวยากรณ์นักพัฒนาดูกรณีขอบที่แตกต่างกันและการอภิปรายมีประโยชน์มากในการผ่าน หากคุณต้องการที่จะผ่านตัวแปรทั้งหมดและความแตกต่างของผู้ประกอบการโปรดดูการอภิปรายการแนะนำคุณสมบัตินี้ในการติดตามปัญหาทับทิมอย่างเป็นทางการ
.?
และตัวเลือกอื่น ๆ ได้รับการพิจารณา แต่&.
เลือก! ดังนั้น&.
จะทำงาน
&.
ไม่.?
เลวเลยนะ อัปเดตคำตอบของฉัน ขอบคุณสำหรับหัวขึ้น!
user.?profile
ควรจะuser&.profile
(ไม่สามารถแก้ไขได้ด้วยตัวเองเพราะมันเป็นเพียงการแก้ไข 1 ตัวอักษร!)
ระวังตัวด้วย! แม้ว่าผู้ให้บริการการนำทางที่ปลอดภัยนั้นสะดวก แต่มันก็ง่ายที่จะหลอกตัวเองให้เปลี่ยนตรรกะด้วย ฉันแนะนำให้หลีกเลี่ยงการใช้มันในการควบคุมการไหล ตัวอย่าง:
str = nil
puts "Hello" if str.nil? || str.empty?
# The above line is different than the below line
puts "Hello" if str&.empty?
ในตัวอย่างแรกstr.nil?
ส่งคืนtrue
และstr.empty?
ไม่ถูกเรียกใช้ทำให้puts
คำสั่งถูกเรียกใช้งาน อย่างไรก็ตามในตัวอย่างที่สองstr&.empty?
ส่งคืนnil
ซึ่งเป็นเท็จและputs
คำสั่งจะไม่ดำเนินการ
str.nil?
จะเป็นจริง (ตามที่คุณพูด) ซึ่งหมายความว่าstr.empty?
จะไม่ถูกเรียก||
ใช้เลย ส่วนที่เหลือของคำสั่งของคุณถูกต้อง
puts "hello" unless str&.present?
(ทางรถไฟเฉพาะสำหรับวิธีการปัจจุบัน)
มันใช้สำหรับการตรวจสอบศูนย์เช่นใน kotlin และรวดเร็วตัวอย่างเช่น กับวัตถุ -> Swift และ Kotlin
model = car?.model
โมเดลนี้สามารถเป็นศูนย์ (Swift) หรือ null (Kotlin) หากเรายังไม่ได้กำหนดค่ารุ่นในคลาสรถยนต์ เราใช้เครื่องหมายและแทนเครื่องหมายคำถามเป็นทับทิม
model = car&.model
ถ้าใช้ car.model ที่ไม่มีเครื่องหมายและและเป็นรุ่นที่ไม่มีระบบจะไม่สามารถทำงานต่อไปได้
try!
วิธีการไม่ใช่try