简体   繁体   English

Kotlin数据类型和Swift数据类型的映射和使用

[英]Mappings and usage of Kotlin data types and Swift data types

Let's say I have a function foo which takes two arguments:假设我有一个 function foo ,它需要两个 arguments:

actual fun foo(list1: List<Long>, list2: List<Double>) {
...
}

According to the https://kotlinlang.org/docs/tutorials/native/apple-framework.html Kotlin's Long type is mapped to KotlinLong and Kotlin's Double is mapped to KotlinDouble .根据https://kotlinlang.org/docs/tutorials/native/apple-framework.html Kotlin 的 Long 类型映射到KotlinLong和 Kotlin 的 Double 映射到KotlinDouble Now I would like to call this function from my iOS App.现在我想从我的 iOS 应用程序中调用这个 function。 Let's say I have two arrays:假设我有两个 arrays:

let list1Numbers = [1000.43, 564121.34, 5617172172.234, 100.7]
let list2Numbers = [2.1, 3.2, 1.7]

For the list2 I could do something like:对于list2 ,我可以执行以下操作:

let list2NumbersKotlin = list2Numbers.map({KotlinDouble.init(double: $0)})

which is not very convenient but will work.这不是很方便,但会起作用。 The list1 is a bit more problematic. list1有点问题。 Since there is no Long in Swift, I do something like由于 Swift 中没有Long ,我做了类似的事情

let list1NumbersKotlin =  list1Numbers.map({KotlinLong.init(longLong: Int64($0))})

Questions:问题:

  1. Is there a better way to do it?有更好的方法吗?

  2. What is a typical approach to deal with such types mapping when using Kotlin as an iOS Framework?使用 Kotlin 作为 iOS 框架时,处理此类类型映射的典型方法是什么? Unfortunately I couldn't find any examples on the Internet.不幸的是,我在 Internet 上找不到任何示例。

  3. Should certain types such as Long be completely avoided if I want to use Kotlin as iOS Framework?如果我想使用 Kotlin 作为 iOS 框架,是否应该完全避免某些类型,例如 Long?

  4. Also, regarding mapping in general: since the Kotlin function此外,关于一般映射:因为 Kotlin function

     fun testDouble(testVal: Double) {}

allows me to pass in Swift the Double directly:允许我直接传入 Swift 的 Double :

HelloKt.testDouble(testVal: Double)

then why does the function那为什么 function

fun testList(testList: List<Double>) {}

not allow me to enter Double array but requires a KotlinDouble array?不允许我输入 Double 数组但需要 KotlinDouble 数组?

HelloKt.testList(testList: [KotlinDouble]){}

Passing a [Double] gives error:传递 [Double] 会产生错误:

Cannot convert value of type '[Double]' to expected argument type '[KotlinDouble]'无法将类型“[Double]”的值转换为预期的参数类型“[KotlinDouble]”

  1. There are multiple ways.有多种方法。

You are talking about collections of data that are on the line between primitive types and objects, which tends to be a special case in Kotlin anyway.您说的是位于原始类型和对象之间的数据的 collections,无论如何,这在 Kotlin 中往往是一种特殊情况。

Speaking to that, in Kotlin, you might want a LongArray and a DoubleArray rather than List<Long> and List<Double> .说到这一点,在 Kotlin 中,您可能需要LongArrayDoubleArray而不是List<Long>List<Double> Coming from Swift, you'll be forced to explicitly box them.来自 Swift,您将被迫明确地将它们装箱。 Kotlin will handle that for you when you're writing Kotlin code, but they're still getting boxed under the hood.当您编写 Kotlin 代码时,Kotlin 会为您处理这个问题,但它们仍然在引擎盖下被装箱。

So, summary, either what you've done above, or take LongArray and DoubleArray as args rather than lists, and do a different translation.因此,总结一下,您在上面所做的事情,或者将LongArrayDoubleArray作为参数而不是列表,并进行不同的翻译。 Either way, you will need to move the data into something Koltin compatible.无论哪种方式,您都需要将数据移动到与 Koltin 兼容的地方。

Obviously, if you put that in a helper function, ugly as it perhaps may be, you only need to do it once.显然,如果你把它放在一个助手 function 中,尽管它可能很丑,你只需要做一次。

  1. Either your method or what I described.无论是你的方法还是我描述的。

  2. Long isn't problematic. Long是没有问题的。 There is a "long" in Swift, it's Int64 . Swift 中有一个“长”,它是Int64 Having to wrap values like that isn't fun, but Kotlin and Swift are different languages, and there are compromises.必须包装这样的值并不好玩,但是 Kotlin 和 Swift 是不同的语言,并且存在妥协。 If you use Int in Kotlin instead of Long , you'll need to wrap a Swift Int with Int32 .如果您在 Kotlin 中使用Int而不是Long ,则需要用Int32包装 Swift Int A Kotlin Int is, in that sense, "problematic" in the same way.从这个意义上说,Kotlin Int以同样的方式“有问题”。 You need to specify which precision int you're using.您需要指定您使用的精度 int 。

  3. In Kotlin, List<Long> is a list of Long objects, while just a Long is a primitive value.在 Kotlin 中, List<Long>Long对象的列表,而Long是原始值。 Kotlin hides the boxing of those values, but they are boxed. Kotlin 隐藏了这些值的装箱,但它们是装箱的。 The Swift/Kotlin interface is forcing you to be more explicit. Swift/Kotlin 接口迫使您更加明确。 If you want primitive values, use the ___Array forms mentioned above.如果您想要原始值,请使用上面提到的 ___Array forms。

Here is the mapping list between Kotlin and Swift types:以下是 Kotlin 和 Swift 类型之间的映射列表:

https://kotlinlang.org/docs/apple-framework.html#kotlin-numbers-and-nsnumber https://kotlinlang.org/docs/apple-framework.html#kotlin-numbers-and-nsnumber

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM