ยามสามารถปรับปรุงความชัดเจน
เมื่อคุณใช้ยามคุณมีความคาดหวังที่สูงกว่ามากสำหรับผู้พิทักษ์ที่จะประสบความสำเร็จและมันค่อนข้างสำคัญที่ถ้ามันไม่สำเร็จคุณก็แค่ต้องการออกจากขอบเขตก่อนเวลา เช่นเดียวกับที่คุณเฝ้าดูว่ามีไฟล์ / รูปภาพอยู่หรือไม่หากอาร์เรย์ว่างเปล่าหรือไม่
func icon() -> UIImage {
guard let image = UIImage(named: "Photo") else {
return UIImage(named: "Default")! //This is your fallback
}
return image //-----------------you're always expecting/hoping this to happen
}
หากคุณเขียนโค้ดด้านบนด้วย if-let มันบ่งบอกถึงนักพัฒนาการอ่านว่ามันมากกว่า 50-50 แต่ถ้าคุณใช้ยามคุณจะเพิ่มความชัดเจนให้กับรหัสของคุณและมันก็บอกเป็นนัยว่าฉันคาดหวังว่าสิ่งนี้จะทำงานได้ 95% ของเวลา ... ถ้ามันล้มเหลวฉันไม่รู้ว่าทำไมมันถึง; มันไม่น่าเป็นไปได้มาก ... แต่จากนั้นให้ใช้ภาพเริ่มต้นนี้แทนหรืออาจแค่ยืนยันด้วยข้อความที่มีความหมายซึ่งอธิบายถึงสิ่งที่ผิดพลาด!
หลีกเลี่ยงguard
เมื่อพวกเขาสร้างผลข้างเคียงยามที่จะนำมาใช้เป็นธรรมชาติไหล หลีกเลี่ยงยามเมื่อelse
ประโยคแนะนำผลข้างเคียง ยามกำหนดเงื่อนไขที่จำเป็นสำหรับรหัสเพื่อดำเนินการอย่างถูกต้องโดยเสนอทางออกก่อนกำหนด
เมื่อคุณทำการคำนวณที่มีนัยสำคัญในสาขาบวกให้ refactor จากif
เป็นguard
คำสั่งและส่งกลับค่าทางเลือกในelse
ประโยค
จาก: หนังสือ Swift Style ของ Erica Sadun
นอกจากนี้จากคำแนะนำข้างต้นและรหัสที่สะอาดจึงมีแนวโน้มที่คุณจะต้องการ / จำเป็นต้องเพิ่มคำยืนยันลงในคำสั่งการป้องกันที่ล้มเหลวซึ่งจะช่วยเพิ่มความสามารถในการอ่านและทำให้ชัดเจนสำหรับนักพัฒนาคนอื่น ๆ ว่าคุณคาดหวังอะไร
guard let image = UIImage(named: selectedImageName) else { // YESSSSSS
assertionFailure("Missing \(selectedImageName) asset")
return
}
guard let image = UIImage(named: selectedImageName) else { // NOOOOOOO
return
}
จาก: หนังสือ Swift Style ของ Erica Sadun + ดัดแปลงบางส่วน
(คุณจะไม่ใช้คำยืนยัน / เงื่อนไขเบื้องต้นสำหรับif-let
s ดูเหมือนจะไม่ถูกต้อง)
การใช้ยามยังช่วยปรับปรุงความชัดเจนโดยหลีกเลี่ยงปิรามิดแห่งการลงโทษ ดูคำตอบของ Nitin
Guard สร้างตัวแปรใหม่
มีความแตกต่างที่สำคัญอย่างหนึ่งที่ฉันเชื่อว่าไม่มีใครอธิบายได้ดี
อย่างไรก็ตามทั้งสองguard let
และif let
แกะตัวแปร
ด้วยguard let
คุณกำลังสร้างตัวแปรใหม่ที่จะอยู่นอกelse
คำสั่ง
เมื่อif let
คุณไม่ได้สร้างตัวแปรใหม่ใด ๆ หลังจากคำสั่ง else คุณจะต้องป้อนรหัสบล็อกเท่านั้นหากตัวเลือกนั้นไม่ใช่ศูนย์ ตัวแปรที่สร้างขึ้นใหม่มีอยู่เฉพาะในบล็อกโค้ดเท่านั้นหลังจากนั้นไม่ได้!
guard let:
func someFunc(blog: String?) {
guard let blogName = blog else {
print("some ErrorMessage")
print(blogName) // will create an error Because blogName isn't defined yet
return
}
print(blogName) // You can access it here ie AFTER the guard statement!!
//And if I decided to do 'another' guard let with the same name ie 'blogName' then I would create an error!
guard let blogName = blog else { // errorLine: Definition Conflicts with previous value.
print(" Some errorMessage")
return
}
print(blogName)
}
if-let:
func someFunc(blog: String?) {
if let blogName1 = blog {
print(blogName1) // You can only access it inside the code block. Outside code block it doesn't exist!
}
if let blogName1 = blog { // No Error at this line! Because blogName only exists inside the code block ie {}
print(blogName1)
}
}
สำหรับข้อมูลเพิ่มเติมเกี่ยวกับif let
do โปรดดู: เหตุใดการประกาศซ้ำการเชื่อมโยงที่เป็นทางเลือกจึงไม่สร้างข้อผิดพลาด
Guard ต้องการการออกจากขอบเขต
(กล่าวถึงในคำตอบของ Rob Napier ด้วย):
คุณต้องguard
กำหนดไว้ใน func จุดประสงค์หลักคือการยกเลิก / ส่งคืน / ออกจากขอบเขตหากไม่เป็นไปตามเงื่อนไข:
var str : String?
guard let blogName1 = str else {
print("some error")
return // Error: Return invalid outside of a func
}
print (blogName1)
สำหรับif let
คุณไม่จำเป็นต้องมีไว้ใน func ใด ๆ :
var str : String?
if let blogName1 = str {
print(blogName1) // You don't get any errors!
}
guard
VS if
มันเป็นมูลค่า noting ว่ามันเป็นที่เหมาะสมมากขึ้นเพื่อดูคำถามนี้เป็นguard let
VS if let
และVSguard
if
แบบสแตนด์อโลนif
ไม่ได้ทำแกะใด ๆ guard
ไม่ไม่สแตนด์อโลน ดูตัวอย่างด้านล่าง nil
มันไม่ได้ออกจากต้นถ้ามีค่าเป็น ไม่มีค่าที่เป็นทางเลือก มันเพิ่งออกก่อนเวลาหากไม่เป็นไปตามเงื่อนไข
let array = ["a", "b", "c"]
func subscript(at index: Int) -> String?{
guard index > 0, index < array.count else { return nil} // exit early with bad index
return array[index]
}
if let
เมื่อnon-nil
เคสถูกต้อง ใช้guard
เมื่อnil
กรณีนี้แสดงถึงข้อผิดพลาดบางประเภท