ใน Kotlin มีเทียบเท่ากับรหัส Swift ด้านล่างหรือไม่?
if let a = b.val {
}
else {
}
ใน Kotlin มีเทียบเท่ากับรหัส Swift ด้านล่างหรือไม่?
if let a = b.val {
}
else {
}
คำตอบ:
คุณสามารถใช้let
ฟังก์ชันนี้:
val a = b?.let {
// If b is not null.
} ?: run {
// If b is null.
}
โปรดทราบว่าคุณต้องเรียกใช้run
ฟังก์ชันเฉพาะเมื่อคุณต้องการบล็อกโค้ดเท่านั้น คุณสามารถลบrun
-block ออกได้หากคุณมี oneliner หลัง elvis-operator ( ?:
) เท่านั้น
ทราบว่าrun
บล็อกจะมีการประเมินทั้งหากb
เป็นโมฆะหรือหากlet
ประเมิน -block null
ไป
ด้วยเหตุนี้คุณจึงต้องการเพียงแค่การif
แสดงออก
val a = if (b == null) {
// ...
} else {
// ...
}
ในกรณีนี้else
-block จะได้รับการประเมินb
ก็ต่อเมื่อไม่เป็นโมฆะ
a
ยังไม่ได้กำหนดไว้ในขอบเขตlet
และrun
. แต่คุณสามารถเข้าถึงค่าของb
ภายในที่มีพารามิเตอร์โดยปริยายlet
it
สิ่งนี้มีจุดประสงค์เดียวกับที่ฉันเดา
a
ก่อนบล็อกโค้ดเหล่านั้น และa
สามารถเข้าถึงได้ภายใน.
a
อะไร? ถ้าเป็นb
เช่นนั้นก็it
มีจุดประสงค์เดียวกัน มันกำหนดใหม่a
ด้วยผลลัพธ์ของval
-block หรือไม่?
it
จากในlet
บล็อกเท่านั้น ผลของlet
หรือบล็อกจะได้รับมอบหมายให้run
a
ผลลัพธ์คือนิพจน์สุดท้ายในบล็อก คุณใช้การมอบหมายหลังจาก let
/ run
เสร็จสิ้นเช่นเดียวกับที่คุณทำกับงานอื่น ๆ ตามปกติ
ก่อนอื่นให้แน่ใจว่าเราเข้าใจความหมายของสำนวน Swift ที่ให้มา:
if let a = <expr> {
// then-block
}
else {
// else-block
}
ซึ่งหมายความว่า: "ถ้า<expr>
ผลลัพธ์เป็น non-nil ทางเลือกให้ป้อนthen
-block ที่มีสัญลักษณ์a
ผูกไว้กับค่าที่ไม่ได้else
ปิดกั้นมิฉะนั้นให้ป้อนบล็อก
โดยเฉพาะอย่างยิ่งโปรดทราบว่าa
ถูกผูกไว้ภายในthen
-blockเท่านั้น ใน Kotlin คุณสามารถรับสิ่งนี้ได้อย่างง่ายดายโดยโทร
<expr>?.also { a ->
// then-block
}
และคุณสามารถเพิ่มelse
-block ดังนี้:
<expr>?.also { a ->
// then-block
} ?: run {
// else-block
}
ส่งผลให้มีความหมายเช่นเดียวกับสำนวน Swift
คำตอบของฉันคือแมวคัดลอกจากตัวอื่น ๆ ทั้งหมด อย่างไรก็ตามฉันไม่สามารถเข้าใจการแสดงออกของพวกเขาได้อย่างง่ายดาย ดังนั้นฉันเดาว่ามันจะเป็นการดีที่จะให้คำตอบที่เข้าใจได้มากขึ้น
อย่างรวดเร็ว:
if let a = b.val {
//use "a" as unwrapped
}
else {
}
ใน Kotlin:
b.val?.let{a ->
//use "a" as unwrapped
} ?: run{
//else case
}
let
แทนalso
วิธีที่run
บล็อกจะดำเนินการเมื่อใดก็ตามที่let
บล็อกกลับnull
มาซึ่งไม่ใช่สิ่งที่เราต้องการ
ไม่เหมือน Swift ตรงที่ไม่จำเป็นต้องแกะอุปกรณ์เสริมก่อนใช้ใน Kotlin เราสามารถตรวจสอบได้ว่าค่านั้นไม่เป็นโมฆะหรือไม่และคอมไพลเลอร์ติดตามข้อมูลเกี่ยวกับการตรวจสอบที่คุณดำเนินการและอนุญาตให้ใช้โดยไม่ได้ปิดกั้น
ใน Swift:
if let a = b.val {
//use "a" as unwrapped
} else {
}
ใน Kotlin:
if b.val != null {
//use "b.val" as unwrapped
} else {
}
อ้างอิงเอกสาร: (null-safety)สำหรับกรณีการใช้งานเพิ่มเติมดังกล่าว
if let
คำให้การ.Swift's Optional Binding
( if-let
คำสั่งที่เรียกว่า) ใช้เพื่อค้นหาว่าตัวเลือกมีค่าหรือไม่และถ้าเป็นเช่นนั้นเพื่อให้ค่านั้นพร้อมใช้งานเป็นค่าคงที่ชั่วคราวหรือตัวแปร ดังนั้นOptional Binding
สำหรับif-let
คำสั่งมีดังนี้:
if-let
คำสั่งของ Swift :
let b: Int? = 50
if let a = b {
print("Good news!")
} else {
print("Equal to 'nil' or not set")
}
/* RESULT: Good news! */
ใน Kotlin เช่นเดียวกับใน Swift เพื่อหลีกเลี่ยงข้อขัดข้องที่เกิดจากการพยายามเข้าถึงค่า null เมื่อไม่ได้คาดไว้จะมีการจัดเตรียมไวยากรณ์เฉพาะ (เช่นb.let { }
ในตัวอย่างที่สอง) ไว้สำหรับการคลายการตัดอย่างถูกต้องnullable types
:
Kotlin เทียบเท่า 1ใน
if-let
คำสั่งของ Swift :
val b: Int? = null
val a = b
if (a != null) {
println("Good news!")
} else {
println("Equal to 'null' or not set")
}
/* RESULT: Equal to 'null' or not set */
let
ฟังก์ชันของ Kotlin เมื่อใช้ร่วมกับตัวดำเนินการโทรปลอดภัย?:
จะให้วิธีที่กระชับในการจัดการนิพจน์ที่เป็นโมฆะ
Kotlin เทียบเท่า 2 (ฟังก์ชัน Inline let และ Elvis Operator)ของ
if-let
คำสั่งของ Swift :
val b: Int? = null
val a = b.let { nonNullable -> nonNullable } ?: "Equal to 'null' or not set"
println(a)
/* RESULT: Equal to 'null' or not set */
guard let
คำให้การ.guard-let
คำสั่งใน Swift นั้นเรียบง่ายและทรงพลัง ตรวจสอบเงื่อนไขบางอย่างและหากประเมินว่าเป็นเท็จelse
คำสั่งจะดำเนินการซึ่งโดยปกติจะออกจากเมธอด
ลองสำรวจ
guard-let
คำสั่งของ Swift :
let b: Int? = nil
func testIt() {
guard let a = b else {
print("Equal to 'nil' or not set")
return
}
print("Good news!")
}
testIt()
/* RESULT: Equal to 'nil' or not set */
ผลที่คล้ายกันของ Kotlinจาก
guard-let
คำสั่งของ Swift :
ไม่เหมือน Swift ใน Kotlin ไม่มีคำสั่งยามเลย อย่างไรก็ตามคุณสามารถใช้Elvis Operator
- ?:
เพื่อให้ได้เอฟเฟกต์ที่คล้ายกัน
val b: Int? = 50
fun testIt() {
val a = b ?: return println("Equal to 'null' or not set")
return println("Good news!")
}
testIt()
/* RESULT: Good news! */
หวังว่านี่จะช่วยได้
นี่คือวิธีรันโค้ดเฉพาะเมื่อname
ไม่เป็นโมฆะ:
var name: String? = null
name?.let { nameUnwrapp ->
println(nameUnwrapp) // not printed because name was null
}
name = "Alex"
name?.let { nameUnwrapp ->
println(nameUnwrapp) // printed "Alex"
}
let
ไม่ แต่คำถามคือเกี่ยวกับelse
กลยุทธ์ที่รันถ้าวัตถุที่ถูกเรียกว่าเป็นlet
null
Swift มีวิธีที่เป็นธรรมชาติมากขึ้น (โต้แย้งได้) แต่หลังจากทำทั้ง Kotlin และ Swift เป็นจำนวนมากฉันหวังว่า Kotlin จะมีการแกะแบบง่ายๆเหมือนที่ Swift ทำ
นี่คือตัวแปรของฉัน จำกัด เฉพาะกรณี "if not null" ที่พบบ่อย
ก่อนอื่นกำหนดสิ่งนี้ไว้ที่ใดที่หนึ่ง:
inline fun <T> ifNotNull(obj: T?, block: (T) -> Unit) {
if (obj != null) {
block(obj)
}
}
มันอาจจะinternal
เพื่อหลีกเลี่ยงความขัดแย้ง
ตอนนี้แปลงรหัส Swift นี้:
if let item = obj.item {
doSomething(item)
}
สำหรับรหัส Kotlin นี้:
ifNotNull(obj.item) { item ->
doSomething(item)
}
โปรดทราบว่าเช่นเคยกับบล็อกใน Kotlin คุณสามารถวางอาร์กิวเมนต์และใช้it
:
ifNotNull(obj.item) {
doSomething(it)
}
แต่ถ้าบล็อกมีมากกว่า 1-2 บรรทัดก็น่าจะดีที่สุด
สิ่งนี้คล้ายกับ Swift เท่าที่ฉันจะหาได้
มีวิธีที่คล้ายกันใน kotlin เพื่อให้ได้รูปแบบ if-let ของ Swift
if (val a = b) {
a.doFirst()
a.doSecond()
}
คุณยังสามารถกำหนดค่าที่เป็นโมฆะได้หลายค่า
if (val name = nullableName, val age = nullableAge) {
doSomething(name, age)
}
แนวทางแบบนี้จะเหมาะสมกว่าหากใช้ค่าที่เป็นโมฆะได้มากกว่า 1 ครั้ง ในความคิดของฉันมันช่วยในด้านประสิทธิภาพเนื่องจากค่าที่เป็นโมฆะจะถูกตรวจสอบเพียงครั้งเดียว
ที่มา: Kotlin Discussion
ฉันกำลังเพิ่มคำตอบนี้เพื่อชี้แจงคำตอบที่ยอมรับเนื่องจากมันใหญ่เกินไปสำหรับความคิดเห็น
รูปแบบทั่วไปที่นี่คือคุณสามารถใช้การรวมกันของฟังก์ชันขอบเขตที่มีอยู่ใน Kotlin โดยคั่นด้วยตัวดำเนินการเอลวิสดังนี้:
<nullable>?.<scope function> {
// code if not null
} :? <scope function> {
// code if null
}
ตัวอย่างเช่น:
val gradedStudent = student?.apply {
grade = newGrade
} :? with(newGrade) {
Student().apply { grade = newGrade }
}
ตัวเลือกที่สะอาดที่สุดในความคิดของฉันคือนี่
สวิฟท์:
if let a = b.val {
} else {
}
Kotlin
b.val.also { a ->
} ?: run {
}
รวดเร็วถ้าให้คำสั่งใน Kotlin
คำตอบสั้น ๆ คือใช้IF-ELSEอย่างง่ายตามเวลาของความคิดเห็นนี้ไม่มีสิ่งที่เทียบเท่าใน Kotlin LET
if(A.isNull()){
// A is null
}else{
// A is not null
}
a
ไม่สามารถเข้าถึงภายในlet
และrun
ปิดกั้นได้