Ruby มีโอเปอเรเตอร์ที่น่าสนใจมากมาย
ถูกใจ :
- ตัวดำเนินการยานอวกาศ (
<=>) - ตัวดำเนินการกำหนดโมดูโล (
%=) - สามเท่ากับ (
===) โอเปอเรเตอร์ - มากกว่า (
>) &น้อยกว่า (<) - ไม่เท่ากับ (
!=)
สิ่งที่คุณอาจไม่ทราบก็คือตัวดำเนินการเหล่านี้จำนวนมากเป็น วิธี Ruby .
หมายความว่า…
คุณสามารถเขียนทับสิ่งที่พวกเขาทำและใช้เพื่อกำหนดพฤติกรรมที่กำหนดเองในชั้นเรียนของคุณเองได้
ตัวอย่างเช่น โดยการกำหนด == คุณสามารถบอก Ruby ถึงวิธีเปรียบเทียบสองวัตถุในคลาสเดียวกันได้
ตอนนี้ :
มาดูตัวอย่างกันเพื่อให้คุณเข้าใจภาพรวมคร่าวๆ ว่าตัวดำเนินการ Ruby เหล่านี้ทำงานอย่างไร &วิธีใช้งาน ในรหัสของคุณ
นี่เป็นหัวข้อสำคัญหากคุณต้องการเข้าใจ Ruby จริงๆ
สารบัญ
- ตัวดำเนินการลอจิก 1 รูบี้
- ตัวดำเนินการเลขคณิต 2 รูบี้
- 3 ผู้ดำเนินการมอบหมาย (==, +=, ||=)
- 4 Unary Operators คืออะไร
- ตัวดำเนินการ Ruby Splat 5 ตัว (พร้อมตัวอย่าง)
- ตัวดำเนินการจับคู่ 6 ตัว (=~)
- 7 Ruby Ternary Operator (ตัวดำเนินการเครื่องหมายคำถาม)
- 8 The Shovel / Push Operator (<<)
- 9 Triple Equals Operator (มากกว่าความเท่าเทียมกัน)
- 10 ตัวดำเนินการ Safe Navigator (&.)
- 11 ตารางลำดับความสำคัญของตัวดำเนินการ
- 12 สรุป
- 12.1 ที่เกี่ยวข้อง
ตัวดำเนินการเชิงตรรกะของทับทิม
อันดับแรก เราจะดูตัวดำเนินการเชิงตรรกะ
คุณสามารถใช้โอเปอเรเตอร์เหล่านี้เพื่อช่วยเปรียบเทียบสองออบเจ็กต์ และตัดสินใจตามผลลัพธ์
นี่คือตาราง:
| ตัวดำเนินการ | คำอธิบาย |
|---|---|
| < | น้อยกว่า |
| > | มากกว่า |
| >= | มากกว่าหรือเท่ากับ |
| <= | น้อยกว่าหรือเท่ากับ |
| == | เท่ากับ |
| != | ไม่เท่ากับ |
| <=> | มากกว่า เท่ากัน หรือน้อยกว่า |
โอเปอเรเตอร์ทั้งหมดนี้เป็นเมธอด และ ส่งคืนค่าบูลีน ยกเว้นผู้ดำเนินการยานอวกาศ ตัวดำเนินการยานอวกาศส่งกลับค่า 1 (มากกว่า), 0 (เท่ากับ) หรือ -1 (น้อยกว่า)
นี่คือตัวอย่างวิธีการใช้ > โอเปอเรเตอร์:
if orange.stock > 20 # ... end
หากคุณต้องการใช้คู่เท่ากับ (== ) โอเปอเรเตอร์กับชั้นเรียนของคุณเอง คุณอาจพบว่ามันไม่ได้ผลในตอนแรก…
ตัวอย่าง :
class Fruit
def initialize(name)
@name = name
end
end
orange1 = Fruit.new("orange")
orange2 = Fruit.new("orange")
orange1 == orange2
# false
เหตุผลก็คือการใช้งานเริ่มต้นของ == คือ BasicObject#==ซึ่งใช้ object_id วิธีตรวจสอบว่าวัตถุสองชิ้นเหมือนกันหรือไม่
คุณสามารถแก้ไขได้ดังนี้:
class Fruit
attr_reader :name
def initialize(name)
@name = name
end
def ==(other)
name == other.name
end
end
เรากำลังพูดถึงความหมายของผลไม้สองผลที่เหมือนกัน:
ต้องมีชื่อเดียวกัน
ตัวดำเนินการเลขคณิตทับทิม
ตัวดำเนินการชุดถัดไปคือตัวดำเนินการเลขคณิต
ไม่มีอะไรใหม่ที่นี่…
5 + 5 # 10 10 * 2 # 20 10 ** 2 # 100
แต่เหมือนกับ == โอเปอเรเตอร์ นี่คือวิธีการ
สิ่งนี้มีประโยชน์เพราะ คุณสามารถกำหนดความหมายของการเพิ่มสองวัตถุเข้าด้วยกัน .
ดังนั้นถ้าคุณมี Order . สองรายการ ออบเจ็กต์ การเพิ่มเข้าด้วยกันจะทำให้คุณมีจำนวนเงินที่ต้องชำระทั้งหมด หรือคุณจะได้รับคำสั่งซื้อใหม่ที่เป็นการรวมกันของคำสั่งซื้อทั้งสองนี้
คุณสามารถกำหนดได้ตรง คุณต้องการให้มันทำงานอย่างไรโดยกำหนด + วิธีการ
โอเปอเรเตอร์อื่นที่คุณอาจไม่คุ้นเคยคือ โอเปอเรเตอร์โมดูโล .
ดูเหมือนเครื่องหมายเปอร์เซ็นต์ (% )
และสิ่งที่ทำคือให้ส่วนที่เหลือของดิวิชั่น .
ตัวอย่าง :
10 % 2 # 0
โมดูโลโอเปอเรเตอร์มีการใช้งานจริง .มากมาย เช่น การหาว่าตัวเลขเป็นเลขคู่หรือคี่ หากตัวเลขถูกหารด้วยตัวอื่น การจำกัดจำนวน เป็นต้น
ตัวดำเนินการมอบหมาย (==, +=, ||=)
ต่อไปคือโอเปอเรเตอร์การมอบหมาย ซึ่งต่างจากโอเปอเรเตอร์ทั้งหมดที่เราเห็นมาจนถึงตอนนี้ สิ่งเหล่านี้ไม่ใช่วิธีการ
คุณมีโอเปอเรเตอร์การมอบหมายพื้นฐาน:
a = 1
แต่คุณยังมีตัวดำเนินการมอบหมายแบบรวม:
a += 5 # 6 a *= 2 # 12
สิ่งเหล่านี้เทียบเท่ากับการอ่านค่าปัจจุบัน &โดยใช้หนึ่งในตัวดำเนินการเลขคณิตกับมัน จากนั้นบันทึกผลลัพธ์ คุณสามารถทำเช่นนี้กับตัวดำเนินการเลขคณิตทั้งหมด รวมทั้งตัวดำเนินการโมดูโล (% )
แต่มีโอเปอเรเตอร์การมอบหมายสองตัวที่ทำงานต่างกัน!
นี่คือ ||= และ &&= .
ต่างกันเพราะไม่เท่ากัน เป็นเวอร์ชันเลขคณิต
อะไร a ||= 100 เป็นสิ่งนี้:
“ถ้า
aไม่มีอยู่จริงหรือหากเป็นfalseหรือnilแล้วกำหนด100ไปที่มันมิฉะนั้นเพียงแค่คืนค่าa”
นิพจน์ที่ใกล้เคียงที่สุดที่ฉันจะได้รับคือ:
(defined?(a) && a) ? a : a = 100
สิ่งนี้มีประโยชน์หากคุณต้องการบันทึกผลลัพธ์ของการคำนวณที่ช้าหรือคำขอ API ซึ่งเป็นกระบวนการที่เรียกว่า “การบันทึก”
Unary Operators คืออะไร
จนถึงตอนนี้ คุณเคยเห็นตัวดำเนินการที่ทำงานด้วย 2 ค่าเท่านั้น แต่ยังมี ตัวดำเนินการที่ทำงานด้วยค่าเดียวเท่านั้น เราเรียกสิ่งเหล่านี้ว่า “ยูนารีโอเปอเรเตอร์”
ตัวอย่างเช่น :
+"abc"
การดำเนินการนี้จะสร้างสำเนาของสตริงที่ตรึงไว้ไม่แน่นอน
คุณสามารถกำหนดโอเปอเรเตอร์เอกนารีของคุณเองได้ (+ / - ) แต่คุณต้องมีรูปแบบพิเศษบางอย่าง
ตัวอย่าง :
class String
def +@
frozen? ? self.dup : self
end
end
str = "abc".freeze
p (+str).frozen?
# false
ฉันต้องใช้วงเล็บที่นี่เนื่องจากตัวดำเนินการมีความสำคัญกว่าตัวดำเนินการเอกนารี
มี !! . ด้วยนะ ซึ่งไม่ใช่วิธีการ:
!!123 # true !!nil # false
อันนี้มีประโยชน์เพราะ จะเปลี่ยนค่าเป็นบูลีน .
แล้วคุณมี ! ซึ่งเหมือนกันแต่ให้ค่าบูลีนตรงข้ามกับคุณ
ตัวอย่าง :
!true # false !!true # true !false # true
ตัวดำเนินการ Ruby Splat (พร้อมตัวอย่าง)
ตัวดำเนินการเครื่องหมาย (* ) น่าสนใจเพราะมันทำสิ่งที่คุณทำไม่ได้หากไม่มีมัน
สมมติว่าคุณมีอาร์เรย์ดังนี้:
attributes = [:title, :author, :category]
และคุณต้องการใช้อาร์เรย์นี้กับวิธีการที่รับอาร์กิวเมนต์ตัวแปร เช่น attr_reader .
จากนั้นคุณสามารถทำได้:
attr_reader *attributes
ตัวดำเนินการเครื่องหมาย แปลงอาร์เรย์เป็นรายการองค์ประกอบ ดังนั้นมันจึงเหมือนกับการถอดอาร์เรย์และแทนที่ด้วยทุกสิ่งที่อยู่ภายใน
กล่าวอีกนัยหนึ่ง ตัวอย่างสุดท้ายแปลว่า:
attr_reader :title, :author, :category
นั่นคือพลังของตัวดำเนินการ splat 🙂
ตัวดำเนินการจับคู่ (=~)
โอเปอเรเตอร์ Ruby ที่ดูตลกๆ นี้คืออะไร (=~ ) ด้วยตัวหนอน?
เป็นโอเปอเรเตอร์ที่ตรงกัน!
ช่วยให้คุณค้นหาดัชนีอย่างรวดเร็วโดยใช้นิพจน์ทั่วไป
นี่คือตัวอย่าง:
"3oranges" =~ /[0-9]/ # 0
ค้นหาตัวเลข &ส่งคืนดัชนีภายในสตริงที่พบการจับคู่ครั้งแรก มิฉะนั้นจะคืนค่าเป็นศูนย์
นอกจากนี้ คุณมี !~ โอเปอเรเตอร์ ซึ่งเป็นโอเปอเรเตอร์ “ไม่ตรงกัน”
ตัวอย่าง :
"abc" !~ /[0-9]/ # false
คุณจะได้รับ true หรือ false ด้วยสิ่งนี้ ไม่มีดัชนี ดังนั้นโปรดระลึกไว้เสมอว่า
Ruby Ternary Operator (ตัวดำเนินการเครื่องหมายคำถาม)
ถ้าคุณชอบโค้ดที่กะทัดรัดและสั้น คุณจะต้องหลงรัก Ruby ternary operator
เป็นวิธีการเขียนคำสั่ง if/else แบบกระชับ
หน้าตาเป็นแบบนี้ :
condition ? true : false
นี่คือตัวอย่าง :
"".size == 0 ? "Empty string" : "Non-empty string"
นี่คือวิธีการทำงาน :
ส่วนแรกของโอเปอเรเตอร์ ternary กำหนดเงื่อนไข ("".size == 0 )
แล้วคุณมีสัญลักษณ์เครื่องหมายคำถาม (? )
หลังจากนั้น คุณจะได้ค่าส่งคืนสำหรับ เมื่อเงื่อนไขนี้เป็นจริง .
แล้วโคลอน (: )
และส่วนสุดท้ายเป็นค่าส่งคืนสำหรับ เมื่อเงื่อนไขนี้เป็นเท็จ นี่จะเป็น else ในนิพจน์เงื่อนไขแบบเต็ม
พลั่ว / พลั่ว (<<)
โอเปอเรเตอร์นี้ (<< ) เป็นวิธีการด้วย ดังนั้นมันจึงเปลี่ยนสิ่งที่มันทำขึ้นอยู่กับวัตถุที่คุณกำลังทำงานด้วย
ตัวอย่างเช่น สำหรับอาร์เรย์ เป็นเพียงนามแฝงสำหรับ push วิธีการ
animals = [] animals << "cat"
ด้วยสตริงจะต่อท้าย:
"" << "cat"
และด้วย Integers จะทำ "left shift" ซึ่งหมุนบิตทั้งหมดไปทางซ้าย
2 << 1 # 4 2 << 2 # 8 2 << 3 # 16
ตัวดำเนินการ Triple Equals (มากกว่าความเท่าเทียมกัน)
โอเปอเรเตอร์สุดท้ายของเราในวันนี้จะเกี่ยวกับโอเปอเรเตอร์เท่ากับสามเท่า (=== )
วิธีนี้เป็นวิธีหนึ่งเช่นกัน และปรากฏในที่ที่คุณคาดไม่ถึง
ตัวอย่างเช่น ในกรณีคำสั่ง:
case "bacon" when String puts "It's a string!" when Integer puts "It's an integer" end
Ruby กำลังเรียก === วิธีการเรียนที่นี่
ชอบสิ่งนี้:
String === "bacon"
สิ่งนี้เปรียบเทียบคลาสปัจจุบันกับคลาสของอ็อบเจ็กต์อื่น
ดังนั้น จุดประสงค์ของโอเปอเรเตอร์นี้คือการกำหนดความเท่าเทียมกัน ในบริบทของคำชี้แจงกรณีศึกษา
ตัวดำเนินการ Safe Navigator (&.)
คุณอาจต้องการเรียกใช้เมธอดบนออบเจ็กต์ แต่อ็อบเจ็กต์นี้อาจ nil ซึ่งไม่ดีเพราะเรียกเมธอดบน nil มักทำให้เกิดข้อผิดพลาด
ทางออกเดียว :
if user && user.active # ... end
วิธีที่ดีกว่านี้ :
if user&.active # ... end
&.นี้ เป็นตัวดำเนินการเนวิเกเตอร์ที่ปลอดภัย (แนะนำใน Ruby 2.3) ซึ่งเรียกเฉพาะ active วิธีการใน user ถ้าไม่ใช่ nil .
มีประโยชน์มาก!
ตารางลำดับความสำคัญของผู้ดำเนินการ
Ruby ประเมินซอร์สโค้ดของคุณตามรายการลำดับความสำคัญ เช่น สิ่งที่เกิดขึ้นในวิชาคณิตศาสตร์ด้วยการคูณและวงเล็บ
นี่อาจเป็นสาเหตุของข้อผิดพลาดทุกประเภทหากคุณไม่เข้าใจวิธีการทำงาน
นี่คือตาราง จากลำดับความสำคัญสูงไปต่ำ :
| ตัวดำเนินการ |
|---|
| !, ~, unary + |
| ** |
| เอกพจน์ - |
| *, /, % |
| +, - |
| <<,>> |
| & |
| |, ^ |
| >,>=, <, <= |
| <=>, ==, ===, !=, =~, !~ |
| && |
| || |
| ?, : |
| ตัวแก้ไข-ช่วยเหลือ |
| =, +=, -=, *=, /=, %= |
| กำหนด? |
| ไม่ |
| หรือ และ |
| ตัวแก้ไข-if, ตัวแก้ไข-เว้นแต่, ตัวแก้ไข-ในขณะ, ตัวแก้ไข-จนถึง |
| { } บล็อก |
| ทำ ... จบบล็อก |
ด้วยตัวแก้ไขบางอย่าง มันหมายถึงเวอร์ชันบรรทัดเดียวของคำหลักเหล่านี้
ตัวอย่าง :
puts "awesome" if blog_name == "rubyguides"
ต่อไปนี้คือตัวอย่างที่ลำดับความสำคัญของบล็อกอาจทำให้คุณประหลาดใจ:
# Returns array with uppercase characters
p ["a", "b", "c"].map { |character| character.upcase }
# Returns Enumerator object
p ["a", "b", "c"].map do |character|
character.upcase
end
ในกรณีแรกมันทำงานตามที่คาดไว้ ในกรณีที่สองบล็อกมีความสำคัญต่ำกว่าดังนั้น map คิดว่าไม่มีการบล็อก &ส่งคืนตัวแจงนับ
สรุป
คุณได้เรียนรู้เกี่ยวกับโอเปอเรเตอร์หลายตัวของ Ruby ตั้งแต่ตัวดำเนินการเลขคณิต ไปจนถึงตรรกะ &แม้แต่ตัวดำเนินการเอกนารีที่คลุมเครือมากขึ้น
ตัวดำเนินการเหล่านี้เป็นวิธีการที่คุณสามารถใช้ในคลาสของคุณเองได้จริง ๆ
หวังว่าคุณจะพบว่าสิ่งนี้มีประโยชน์และน่าสนใจ!
ขอบคุณที่อ่านนะคะ 🙂