ตัวดำเนินการตามเงื่อนไข ( ? :
) ใช้งานใน Ruby อย่างไร
เช่นนี้ถูกต้องหรือไม่
<% question = question.size > 20 ? question.question.slice(0, 20)+"..." : question.question %>
ตัวดำเนินการตามเงื่อนไข ( ? :
) ใช้งานใน Ruby อย่างไร
เช่นนี้ถูกต้องหรือไม่
<% question = question.size > 20 ? question.question.slice(0, 20)+"..." : question.question %>
คำตอบ:
มันเป็นตัวดำเนินการที่ประกอบไปด้วยสามตัวและทำงานเหมือนใน C (ไม่ต้องใช้วงเล็บ) มันเป็นสำนวนที่ใช้งานได้:
if_this_is_a_true_value ? then_the_result_is_this : else_it_is_this
อย่างไรก็ตามใน Ruby if
ยังเป็นนิพจน์ดังนี้: if a then b else c end
=== a ? b : c
ยกเว้นประเด็นที่สำคัญกว่า ทั้งคู่เป็นการแสดงออก
ตัวอย่าง:
puts (if 1 then 2 else 3 end) # => 2
puts 1 ? 2 : 3 # => 2
x = if 1 then 2 else 3 end
puts x # => 2
โปรดทราบว่าในกรณีแรกต้องใช้วงเล็บ (มิฉะนั้น Ruby จะสับสนเพราะคิดว่ามันเป็นputs if 1
ขยะพิเศษหลังจากนั้น) แต่ไม่จำเป็นต้องใช้ในกรณีสุดท้ายเนื่องจากปัญหาดังกล่าวไม่เกิดขึ้น
คุณสามารถใช้แบบฟอร์ม "long-if" เพื่อให้สามารถอ่านได้หลายบรรทัด:
question = if question.size > 20 then
question.slice(0, 20) + "..."
else
question
end
nil
false
ไม่ปกติแน่นอน
puts true ? "true" : "false"
=> "true"
puts false ? "true" : "false"
=> "false"
puts (true ? "true" : "false")
ด้วยวงเล็บ มิฉะนั้นคำสั่งของการดำเนินการจะไม่ชัดเจน เมื่อฉันอ่านสิ่งนี้ครั้งแรกฉันรู้สึกสับสนเมื่อฉันอ่านตามที่ (puts true) ? "true" : "false"
คาดไว้ว่าputs
จะส่งคืนบูลีนซึ่งกลายเป็นค่าสตริง
การใช้ ERB ของคุณแนะนำว่าคุณอยู่ใน Rails ถ้าเป็นเช่นนั้นให้พิจารณาtruncate
ผู้ช่วยที่มีอยู่แล้วซึ่งจะทำงานให้คุณ:
<% question = truncate(question, :length=>30) %>
@pst ให้คำตอบที่ดี แต่ฉันอยากจะพูดถึงว่าใน Ruby ผู้ประกอบการที่ประกอบไปด้วยสามบรรทัดถูกเขียนในประโยคเพื่อให้ถูกต้องทางไวยากรณ์ซึ่งแตกต่างจาก Perl และ C ที่เราสามารถเขียนได้หลายบรรทัด:
(true) ? 1 : 0
โดยปกติ Ruby จะทำให้เกิดข้อผิดพลาดหากคุณพยายามแยกมันออกเป็นหลาย ๆ บรรทัด แต่คุณสามารถใช้\
สัญลักษณ์ต่อเนื่องของบรรทัดที่ท้ายบรรทัดและ Ruby จะมีความสุข:
(true) \
? 1 \
: 0
นี่เป็นตัวอย่างง่ายๆ แต่มันมีประโยชน์มากเมื่อต้องจัดการกับบรรทัดที่ยาวกว่าเนื่องจากมันจะช่วยให้โค้ดถูกวางไว้อย่างดี
นอกจากนี้ยังเป็นไปได้ที่จะใช้ ternary ที่ไม่มีตัวอักษรต่อเนื่องของบรรทัดโดยวางโอเปอเรเตอร์ไว้ในบรรทัด แต่ฉันไม่ชอบหรือแนะนำ:
(true) ?
1 :
0
ฉันคิดว่าสิ่งนี้นำไปสู่การอ่านโค้ดที่ยากมากเนื่องจากการทดสอบตามเงื่อนไขและ / หรือผลลัพธ์นั้นยาวขึ้น
ฉันได้อ่านความคิดเห็นที่บอกว่าไม่ควรใช้ผู้ประกอบการที่ประกอบไปด้วยความสับสน แต่นั่นเป็นเหตุผลที่ไม่ดีที่จะไม่ใช้อะไร ด้วยตรรกะเดียวกันเราไม่ควรใช้นิพจน์ทั่วไปตัวดำเนินการช่วง (' ..
' และรูปแบบ "ฟลิปฟล็อป" ที่ดูเหมือนจะไม่รู้จัก) มีประสิทธิภาพเมื่อใช้อย่างถูกต้องดังนั้นเราควรเรียนรู้การใช้อย่างถูกต้อง
ทำไมคุณใส่วงเล็บรอบ
true
?
พิจารณาตัวอย่างของ OP:
<% question = question.size > 20 ? question.question.slice(0, 20)+"..." : question.question %>
การห่อการทดสอบตามเงื่อนไขช่วยให้อ่านง่ายขึ้นเพราะแยกการทดสอบออกเป็นภาพ:
<% question = (question.size > 20) ? question.question.slice(0, 20)+"..." : question.question %>
แน่นอนตัวอย่างทั้งหมดสามารถทำให้อ่านได้ง่ายขึ้นโดยใช้ช่องว่างเพิ่มเติมที่สมเหตุสมผล นี่คือการทดสอบ แต่คุณจะได้รับความคิด:
<% question = (question.size > 20) ? question.question.slice(0, 20) + "..." \
: question.question
%>
หรือเขียนเพิ่มเติมมากกว่าสำนวน:
<% question = if (question.size > 20)
question.question.slice(0, 20) + "..."
else
question.question
end
%>
เป็นเรื่องง่ายที่จะโต้แย้งว่าการอ่านนั้นมีความเลวquestion.question
เช่นกัน
true
?
true
เป็นจริงนั่งอยู่ในสำหรับสิ่งที่จะแสดงออกที่ประเมินหรือtrue
false
เป็นการดีกว่าที่จะกำหนดขอบเขตที่มองเห็นได้เนื่องจากข้อความประกอบไปด้วยส่วนสั้นสามารถเปลี่ยนเป็นเสียงรบกวนทางสายตาได้อย่างรวดเร็วลดความสามารถในการอ่านที่มีผลต่อการบำรุงรักษา
ตัวอย่างง่าย ๆ ที่โอเปอเรเตอร์ตรวจสอบว่ารหัสผู้เล่นเป็น 1 และตั้งรหัสศัตรูขึ้นอยู่กับผลลัพธ์
player_id=1
....
player_id==1? enemy_id=2 : enemy_id=1
# => enemy=2
และฉันพบโพสต์เกี่ยวกับหัวข้อที่ดูเหมือนว่าค่อนข้างเป็นประโยชน์
enemy_id = player_id == 1 ? 2 : 1
ล่ะ
รหัสcondition ? statement_A : statement_B
เทียบเท่า
if condition == true
statement_A
else
statement_B
end
วิธีที่ง่ายที่สุด:
param_a = 1
param_b = 2
result = param_a === param_b ? 'Same!' : 'Not same!'
เนื่องจากparam_a
ไม่เท่ากับparam_b
แล้วresult
ค่าของจะเป็นNot same!
question=question[0,20]
ถ้ามันเล็กกว่า 20 มันจะไม่เปลี่ยนเลย