基于关于使用本期格式的NSString格式,我尝试在使用vararg时实现多平台的格式化,但到目前为止还没有成功。
我所做的
language = Objective-C
---
#import <Foundation/NSString.h>
NSString* format(NSString* format, ...) {
va_list args;
va_start(args, format);
NSString* result = [[NSString alloc] initWithFormat:format arguments:args];
va_end(args);
return result;
}targets {
final def iOSTarget = System.getenv('SDK_NAME')?.startsWith("iphoneos") \
? presets.iosArm64 : presets.iosX64
// https://kotlinlang.org/docs/reference/mpp-dsl-reference.html#native-targets
fromPreset(iOSTarget, 'ios') {
binaries {
}
compilations.main.cinterops {
FoundationInterop {
}
}
}
}StringExtensions.kt中创建commonMainexpect class StringType
expect fun String.format(format: String, vararg args: Any?): StringType?iosMain中actual typealias StringType = String
/**
* https://github.com/JetBrains/kotlin-native/issues/1834
*/
actual fun String.format(format: String, vararg args: Any?): StringType? {
return FoundationInterop.format(format, args as Any)
}val fmt = "http://geomag.bgs.ac.uk/web_service/GMModels/igrf/13/?latitude=%f&longitude=%f&altitude=0&date=%d-%02d-%02d&format=json"
val url = fmt.format(urlFmt, 59.127934932762166, 38.00503518930868, 2020, 1, 3)http://geomag.bgs.ac.uk/web_service/GMModels/igrf/13/?latitude=0.000000&longitude=0.000000&altitude=0&date=43344272-198763328-00&format=json编辑
stringWithFormat给出了相同的结果
actual fun String.format(format: String, vararg args: Any?): StringType? {
return NSString.stringWithFormat(format, args as Any)
}编辑2
发布于 2020-10-23 11:36:29
我证实了你对NSString.stringWithFormat的看法。当我们在Svyatoslav Scherbina的JB官方答案中看到这个特性时,我们可以在这里跟踪您的问题:KT-42925。
作为一种糟糕的解决办法,我建议这样的方法(警告:不穷尽,没有很多索引计数检查.)
import platform.Foundation.NSString
import platform.Foundation.stringWithFormat
actual typealias StringType = String
actual fun String.format(format: String, vararg args: Any?): StringType? {
var returnString = ""
val regEx = "%[\\d|.]*[sdf]|[%]".toRegex()
val singleFormats = regEx.findAll(format).map {
it.groupValues.first()
}.asSequence().toList()
val newStrings = format.split(regEx)
for (i in 0 until args.count()) {
val arg = args[i]
returnString += when (arg) {
is Double -> {
NSString.stringWithFormat(newStrings[i] + singleFormats[i], args[i] as Double)
}
is Int -> {
NSString.stringWithFormat(newStrings[i] + singleFormats[i], args[i] as Int)
}
else -> {
NSString.stringWithFormat(newStrings[i] + "%@", args[i])
}
}
}
return returnString
}但如果这对你来说是个有效的解决办法。

发布于 2020-10-26 09:11:24
你不能将Kotlin各种参数转发给C或Objective。C变量是编译时。这不是科特林特有的限制。不能通过转发所有参数从另一个变量C函数调用变量C函数。
NSString.stringWithFormat(格式,args作为任何形式)
这不对。这一行接受args (即Array),将其转换为Any,并作为单个参数传递。
所以这基本上相当于
[NSString stringWithFormat:format, createKotlinArray(/* all arguments here */)]这不符合你的期望。
因此KT-42925是无效的。您的问题可能通过缺少的特性之一解决:
String.format (KT-25506)。但这并不容易。va_list,例如来自Kotlin Array (KT-42973)。在这种情况下,使用这个变体很容易:https://developer.apple.com/documentation/foundation/nsstring/1407827-initwithformathttps://stackoverflow.com/questions/64495182
复制相似问题