การตกแต่งตัวแปรที่รวดเร็วด้วย“?” (เครื่องหมายคำถาม) และ“!” (เครื่องหมายตกใจ)


107

ฉันเข้าใจว่าใน Swift ตัวแปรทั้งหมดจะต้องตั้งค่าด้วยค่าและโดยการใช้ optionals เราสามารถตั้งค่าตัวแปรที่จะตั้งค่าเป็นค่าnilเริ่มต้นได้

สิ่งที่ฉันไม่เข้าใจคือการตั้งค่าตัวแปรด้วย a !กำลังทำอะไรอยู่เพราะฉันรู้สึกว่า "คลาย" ค่าจากตัวเลือกนี้ ฉันคิดว่าเมื่อทำเช่นนั้นคุณรับประกันได้ว่ามีค่าที่จะแกะในตัวแปรนั้นซึ่งเป็นสาเหตุที่ IBActions และคุณเห็นว่าใช้

พูดง่ายๆก็คือตัวแปรที่จะเริ่มต้นเมื่อคุณทำสิ่งนี้:

var aShape : CAShapeLayer!

และทำไม / เมื่อฉันจะทำสิ่งนี้?


คุณจะทำสิ่งนี้เพื่อบอกว่าตัวแปรเป็น nt nil หลังจากที่คุณตรวจสอบข้อเท็จจริงนี้แล้ว
Matthias

ฉันไม่คิดว่าสิ่งนี้ควรถูกทำเครื่องหมายว่าซ้ำกัน "อะไรเป็นทางเลือก" ไม่ใช่คำถามเดียวกับ "optionals 2 ประเภทต่างกันอย่างไร" ซึ่งเป็นสิ่งที่สวยมากนี้เป็นคำถาม
Jiaaro

@Jiaaro แม้ในกรณีนั้นจะมีคำถามมากมายเกี่ยวกับตัวเลือกตัวเลือกที่ไม่ได้ปิดโดยปริยายและอื่น ๆ คุณสามารถอ้างถึงสิ่งนี้ได้: stackoverflow.com/questions/24272781/…
Jack

@JackWu โอเค แต่ฉันค่อนข้างมั่นใจว่าคำถามนี้ไม่ซ้ำกันเมื่อถูกถาม (มันถูกถามหนึ่งสัปดาห์เต็มก่อนที่ตัวอย่างของคุณ)
Jiaaro

@ Jiaaro คุณมีจุดที่ดีฉันไม่ได้สังเกตว่านี่เก่ากว่า.. บางทีอันอื่นควรถูกทำเครื่องหมายว่าซ้ำกับอันนี้แทน ..
แจ็ค

คำตอบ:


145

ในการประกาศประเภทนั้น!จะคล้ายกับ?. ทั้งสองแบบเป็นทางเลือก แต่!เป็นทางเลือกที่ "ไม่ได้ปิดโดยปริยาย"ซึ่งหมายความว่าคุณไม่จำเป็นต้องแกะออกเพื่อเข้าถึงค่า (แต่ก็ยังสามารถเป็นศูนย์ได้)

นี่คือพฤติกรรมที่เรามีอยู่แล้วในวัตถุประสงค์ -c ค่าอาจเป็นศูนย์ได้และคุณต้องตรวจสอบ แต่คุณยังสามารถเข้าถึงค่าได้โดยตรงราวกับว่ามันไม่ใช่ทางเลือก (โดยมีข้อแตกต่างที่สำคัญคือหากคุณไม่ตรวจหาศูนย์คุณจะได้รับ การทำงานผิดพลาด)

// Cannot be nil
var x: Int = 1

// The type here is not "Int", it's "Optional Int"
var y: Int? = 2

// The type here is "Implicitly Unwrapped Optional Int"
var z: Int! = 3

การใช้งาน:

// you can add x and z
x + z == 4

// ...but not x and y, because y needs to be unwrapped
x + y // error

// to add x and y you need to do:
x + y!

// but you *should* do this:
if let y_val = y {
    x + y_val
}

7
ยังไม่ได้เปิด optionals โดยปริยายอธิบายไว้ในส่วนชื่อ aptly เริ่มต้นในหน้า 56 ของวิฟท์เขียนโปรแกรมภาษา
Caleb

@Caleb ฉันได้เพิ่มลิงก์ไปยังส่วนที่เกี่ยวข้องของเอกสารออนไลน์ซึ่งฉันได้กล่าวถึงตัวเลือกที่ไม่ได้ห่อโดยปริยาย :)
Jiaaro

ข้อมูลที่ดีขอบคุณ โดยทั่วไปแล้วการรักความปลอดภัยที่ Swift บังคับให้เราจนถึงตอนนี้ควรสร้างข้อบกพร่องน้อยลงมาก :)
Jason Renaldo

@Jiaaro: ขอบคุณมากสำหรับการแบ่งปัน ทำให้ผู้ใช้เข้าใจอย่างสมบูรณ์แบบตามตัวอย่างข้างต้น !! :)
Esha

3
ฉันคิดว่าประโยค " นี่เป็นพฤติกรรมที่เรามีอยู่แล้วในวัตถุประสงค์ -c " อาจทำให้สับสนได้ ในวัตถุประสงค์ -c หนึ่งสามารถเข้าถึงnilค่าและ "ทำงาน" กับมันได้อย่างรวดเร็วในการเข้าถึงตัวเลือกที่ไม่ได้ปิดโดยปริยายในขณะที่ไม่มีจะทำให้เกิดข้อยกเว้นรันไทม์
Sascha Wolf
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.