เครื่องหมายอัศเจรีย์เดี่ยวใน Kotlin


152

เครื่องหมายอัศเจรีย์เดี่ยวใน Kotlin หมายถึงอะไร? ฉันเคยเห็นมาสองสามครั้งแล้วโดยเฉพาะเมื่อใช้ Java API แต่ฉันไม่พบในเอกสารหรือใน StackOverflow

คำตอบ:


163

พวกเขาเรียกว่าประเภทแพลตฟอร์มและหมายความว่า Kotlin ไม่รู้ว่าค่านั้นสามารถหรือไม่ได้nullและขึ้นอยู่กับคุณที่จะตัดสินใจว่าเป็นโมฆะหรือไม่

สรุปได้ว่าปัญหาคือการอ้างอิงใด ๆ ที่มาจาก Java อาจเป็นโมฆะและ Kotlin ถูกออกแบบให้มีความปลอดภัยเป็นโมฆะบังคับให้ผู้ใช้ตรวจสอบค่า Java ทุกค่าเป็นโมฆะหรือใช้การเรียกที่ปลอดภัย ( ?.) หรือการยืนยันที่ไม่ใช่ค่าว่าง ( !!). คุณลักษณะเหล่านี้มีประโยชน์มากในโลก Kotlin ที่บริสุทธิ์มีแนวโน้มที่จะกลายเป็นหายนะเมื่อคุณต้องใช้บ่อยเกินไปในการตั้งค่า Kotlin / Java

นี่คือเหตุผลที่เราใช้แนวทางที่รุนแรงและทำให้ระบบประเภทของ Kotlin ผ่อนคลายมากขึ้นเมื่อพูดถึงการทำงานร่วมกันของ Java: ตอนนี้การอ้างอิงที่มาจาก Java ได้ทำเครื่องหมายประเภทไว้เป็นพิเศษ - Kotlin Blog


2
นั่นคือสิ่งที่ดีที่พูดและทำ แต่ผมเพียงแค่อยากรู้สึกที่ดีเรียกมันว่าplatform types
JaydeepW

66

เป็นสัญกรณ์สำหรับประเภทแพลตฟอร์ม :

T!หมายถึง " TหรือT?"


ทำไมไม่Tหมายความว่า " T!หรือT?"
ARST

ท! หมายถึงไม่เป็นโมฆะ T? หมายถึงโมฆะ ทำไม Kotlin ไม่ทำอย่างนั้น ...
Arst

4
เนื่องจากค่าเริ่มต้นที่ดีที่สุดคือ "ไม่เป็นโมฆะ" ด้วยเหตุผลที่ชัดเจนและเป็นการออกแบบที่ดีเพื่อให้ค่าเริ่มต้นเป็นลายเซ็นประเภทที่สั้นที่สุด ดังนั้นจึงTถูกทำให้ "ไม่เป็นโมฆะ" และส่วนที่เหลือนั้นมากหรือน้อยโดยพลการ
voddan

17

ประเภทแพลตฟอร์ม

ชื่อประเภทหรือชื่อคลาสที่ลงท้ายด้วยเครื่องหมายอัศเจรีย์เดี่ยว!เรียกว่าประเภทแพลตฟอร์มใน Kotlin คุณจะพบเมื่อคุณทำงานใน Kotlin ด้วยโค้ด Java เก่าที่ไม่มีข้อมูล nullability

ตัวอย่าง:

ข้อมูล Nullable: Nullable Type

@Nullable Stringใน Java ถือเป็นString?โดย Kotlin

ข้อมูลที่ไม่เป็นค่าว่าง: ประเภทที่ไม่เป็นค่าว่าง

@NotNull Stringใน Java ถือเป็นStringโดย Kotlin

ไม่มีข้อมูล: ประเภทแพลตฟอร์ม

Stringไม่มีคำอธิบายประกอบใน Java ถือว่าString!Kotlin


จะจัดการกับประเภทแพลตฟอร์มอย่างไร?

คุณสามารถทำงานกับแพลตฟอร์มประเภทที่เป็นค่าว่างหรือไม่เป็นค่าว่างก็ได้ คอมไพเลอร์จะอนุญาตให้คุณเรียกใช้เมธอดทั้งหมดในประเภทนี้ เป็นความรับผิดชอบของคุณในการใช้งาน หากคุณรู้ว่าค่าสามารถเป็นโมฆะได้คุณควรเปรียบเทียบกับค่าว่างก่อนที่จะเรียกใช้วิธี ถ้าคุณรู้ว่ามันไม่ใช่โมฆะคุณสามารถใช้มันได้โดยตรง แต่เช่นเดียวกับใน Java คุณจะได้รับข้อยกเว้นหากสมมติฐานของคุณเกี่ยวกับความว่างเปล่านั้นผิด

โปรดทราบว่าคุณไม่สามารถประกาศประเภทแพลตฟอร์มในโค้ด Kotlin ได้เนื่องจากมาจากโค้ด Java เท่านั้น


มรดกและประเภทแพลตฟอร์ม

ในขณะที่แทนที่เมธอด Java ในโค้ด Kotlin คุณมีตัวเลือกในการประกาศพารามิเตอร์และส่งคืนชนิดเป็นโมฆะหรือไม่เป็นค่าว่าง คุณต้องเลือกสิ่งนี้อย่างชาญฉลาดเพราะถ้าคุณตัดสินใจที่จะทำให้พารามิเตอร์ไม่ใช่ค่าว่างคอมไพเลอร์ Kotlin จะสร้างการยืนยันที่ไม่ใช่ค่าว่างสำหรับพารามิเตอร์ที่ไม่ใช่ค่าว่างเหล่านี้ และเมื่อครั้งต่อไปที่คุณเข้าถึงรหัส Kotlin นี้กลับจาก Java และคุณส่งค่า null คุณจะได้รับข้อยกเว้น

หวังว่าจะช่วยคลายข้อสงสัยทั้งหมดของคุณเกี่ยวกับประเภทแพลตฟอร์ม


13

ประเภทของสัญญลักษณ์!ที่เรียกว่าประเภทแพลตฟอร์มซึ่งเป็นชนิดที่มาจาก Javanullและทำให้ส่วนใหญ่อาจจะสามารถ นี่คือสิ่งที่คอมไพเลอร์ Kotlin อนุมานโดยค่าเริ่มต้นเมื่อเรียกใช้ Java (สำหรับกรณีพื้นฐานที่สุดวิธี Java สามารถใส่คำอธิบายประกอบเพื่อหลีกเลี่ยงสิ่งนี้ได้) คุณควรจัดการประเภทแพลตฟอร์มnullableประเภทเว้นแต่คุณจะรู้อย่างแน่นอนว่าเฉพาะ API nullจะไม่กลับ คอมไพเลอร์อนุญาตให้กำหนดประเภทแพลตฟอร์มให้กับตัวแปรทั้งประเภทที่เป็นโมฆะและไม่เป็นค่าว่าง

สัญกรณ์สำหรับประเภทแพลตฟอร์ม

[... ]

T!แปลว่า " T or T?" [... ]

คุณสามารถอ้างถึงประเภทแพลตฟอร์มเป็น "ประเภทของค่าว่างที่ไม่รู้จัก " สิ่งสำคัญที่ควรทราบคือคุณไม่สามารถใช้เครื่องหมายอัศเจรีย์สำหรับประเภทของคุณเองได้ไม่ใช่ส่วนหนึ่งของไวยากรณ์ Kotlin แต่เป็นเพียงสัญกรณ์เท่านั้น


วลีอย่าง 'มากที่สุดอาจจะไม่ช่วยอะไร
Ewan

3

ฉันเคยเห็นมาสองสามครั้งแล้วโดยเฉพาะเมื่อใช้ Java API

ดังกล่าวโดย s1m0nw1, วิธีการT! T or T?คำถามต่อไปคืออะไรT?? นี้เป็นเอกสารอย่างที่https://kotlinlang.org/docs/reference/null-safety.html Kotlin ไม่อนุญาตให้มีองค์ประกอบบางอย่างnullเช่นStringไม่เหมือน Java

เพื่อให้ nulls เราสามารถประกาศตัวแปรเป็นสตริง nullable เขียน String?:

var b: String? = "abc"
b = null // ok

[... ]

b?.length 

สิ่งนี้จะส่งกลับ b.length ถ้า b ไม่ใช่ null มิฉะนั้นจะเป็นค่าว่าง Int?ประเภทของการแสดงออกนี้อยู่


0

ตัดตอนมาจากประเภทแพลตฟอร์มใน Kotlin :

นอกเหนือจากการระบุประเภทอย่างชัดเจนว่าเป็นทางเลือก (เช่นPerson?) Kotlin ยังนำเสนอสัตว์ร้ายอีกตัวหนึ่งที่เรียกว่าPlatform Typeระบุโดยการใส่เครื่องหมายอัศเจรีย์ตัวเดียวแทน (เช่นPerson!) แนวคิดนี้ถูกสร้างขึ้นเพื่อเหตุผลด้านความเข้ากันได้เมื่อเข้าถึงโค้ดจากแพลตฟอร์มที่ไม่ปลอดภัยเช่น Java มักเป็นกรณีที่เมื่อใช้ไลบรารี Java วิธีการต่างๆจะส่งคืนSomeType!เนื่องจากคอมไพเลอร์ Kotlin ไม่สามารถสรุปได้ว่าผลลัพธ์เป็นโมฆะหรือไม่

ตัวอย่างเช่น:

(Mutable)Collection<T>! 

เพียงแค่หมายถึงสิ่งต่อไปนี้: " คอลเลกชัน Java ของ T อาจเปลี่ยนแปลงได้หรือไม่อาจเป็นโมฆะหรือไม่ก็ได้ "

หวังว่านี่จะช่วยได้

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.