Computer >> คอมพิวเตอร์ >  >> การเขียนโปรแกรม >> Ruby

ทุกสิ่งที่คุณจำเป็นต้องรู้เกี่ยวกับโอเปอเรเตอร์ Ruby

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 ตั้งแต่ตัวดำเนินการเลขคณิต ไปจนถึงตรรกะ &แม้แต่ตัวดำเนินการเอกนารีที่คลุมเครือมากขึ้น

ตัวดำเนินการเหล่านี้เป็นวิธีการที่คุณสามารถใช้ในคลาสของคุณเองได้จริง ๆ

หวังว่าคุณจะพบว่าสิ่งนี้มีประโยชน์และน่าสนใจ!

ขอบคุณที่อ่านนะคะ 🙂