首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用vararg的Kotlin原生iOS字符串格式设置

使用vararg的Kotlin原生iOS字符串格式设置
EN

Stack Overflow用户
提问于 2020-10-23 06:47:36
回答 2查看 1.5K关注 0票数 3

基于关于使用本期格式的NSString格式,我尝试在使用vararg时实现多平台的格式化,但到目前为止还没有成功。

我所做的

  • 添加FoundationInterop.def
代码语言:javascript
复制
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;
}
  • 在gradle中编译
代码语言:javascript
复制
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中创建commonMain
代码语言:javascript
复制
expect class StringType

expect fun String.format(format: String, vararg args: Any?): StringType?
  • iosMain
代码语言:javascript
复制
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)
}
  • 示例
代码语言:javascript
复制
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)
  • output -,因为您看到没有由于某种原因而发生值替换,
代码语言:javascript
复制
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给出了相同的结果

代码语言:javascript
复制
actual fun String.format(format: String, vararg args: Any?): StringType? {
    return NSString.stringWithFormat(format, args as Any)
}

编辑2

创建问题https://youtrack.jetbrains.com/issue/KT-42925

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2020-10-23 11:36:29

我证实了你对NSString.stringWithFormat的看法。当我们在Svyatoslav Scherbina的JB官方答案中看到这个特性时,我们可以在这里跟踪您的问题:KT-42925

作为一种糟糕的解决办法,我建议这样的方法(警告:不穷尽,没有很多索引计数检查.)

代码语言:javascript
复制
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
}

但如果这对你来说是个有效的解决办法。

票数 3
EN

Stack Overflow用户

发布于 2020-10-26 09:11:24

你不能将Kotlin各种参数转发给C或Objective。C变量是编译时。这不是科特林特有的限制。不能通过转发所有参数从另一个变量C函数调用变量C函数。

NSString.stringWithFormat(格式,args作为任何形式)

这不对。这一行接受args (即Array),将其转换为Any,并作为单个参数传递。

所以这基本上相当于

代码语言:javascript
复制
[NSString stringWithFormat:format, createKotlinArray(/* all arguments here */)]

这不符合你的期望。

因此KT-42925是无效的。您的问题可能通过缺少的特性之一解决:

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/64495182

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档