小编Rap*_*ita的帖子

Kotlinx 序列化:如何规避反序列化的具体化类型参数?

实际上,主要问题仍然是 Kotlin 中的类没有具体化的类型参数。但这就是为什么在这个特定情况下这让我感到困扰:

假设您有一个包装类Wrapper,它接受一个字符串content和一个类* ,并且可以通过调用函数按需解析为 JSON 来输出检索到的type类的对象:typecontentgetObj()

class Wrapper<T>(private val content: String, /*private val type: KClass<*>*/) {
    fun getObj(): T {
        // ?
    }
}
Run Code Online (Sandbox Code Playgroud)

我想使用 kotlinx.serialization。现在,你可能已经注意到我之前是如何在“class”后面加星号的。原因是:是的,Wrapper必须以某种方式参加目标课程,但是如何呢?它应该只是 typearg (不起作用,因为类型erausre)还是引用KClass(不起作用,因为我需要具体化的 typearg)?

事实是,据我所知,将通用 JSON 解码为可序列化目标类的唯一方法是使用Json.decodeFromString<T>(content),其中T是目标类型,content是 JSON 字符串。现在,T被定义为具体化(以便可以在运行时处理类型)并且只能用另一个具体化的 typearg 或实际的类引用来填充。我无法使用另一个具体化的类型参数,因为我处于类的上下文中,并且类不能具有具体化的类型参数。我也不能使用实际的类引用,因为类的用户应该能够使用不同的目标来构造它,例如他们决定目标是什么,而不是我。

那么,我该如何使用 kotlinx.serialization 来做到这一点?有可能吗?

generics json kotlin kotlin-reified-type-parameters kotlinx.serialization

5
推荐指数
1
解决办法
2029
查看次数

Clang-Tidy 不明确:operator++(int) 应该返回什么?

因此,我一直在致力于Vector一项作业的实现,并在实现迭代器时注意到一些奇怪的 Clang-Tidy 建议。

根据要求的规范,迭代器必须具有iterator& operator++()和重载。iterator operator++(int)现在,当我尝试定义iterator operator++(int),它本质上是复制迭代器,递增指针,然后返回该副本,Clang-Tidy 抱怨道:

重载的“operator++”返回一个非常量对象而不是常量对象类型

(显然)应该通过将返回类型更改为 来解决这个问题const iterator,否则这种技术非常罕见。不过,相应地更改签名会让 Clang-Tidy 再次抱怨:

返回类型“const Vector::iterator”(又名“const Vector::Iterator”)在顶层具有“const”限定,这可能会降低代码可读性,而不会提高 const 正确性

CLion 2020.3.2 中的默认修复操作实际上删除了const,这会带回原始的 Clang-Tidy 警告。

我想知道什么是“正确”的实施方式operator++(int)。在这种情况下我应该忽略 Clang-Tidy 吗?如果是,我应该选择哪个签名?

谢谢!

编辑1

以下帖子没有回答我的问题:Other StackOverflow Question。事实上,在我决定问自己的问题之前我就看到了这篇文章,因为它没有为我解答。问题是在链接的帖子中建议了两个选项:

  1. 按照 clang-tidy 所说的去做,但可能会失去移动语义的好处。
  2. 相反,左值引用限定重载,以模仿小整数。

(1) 的意思正是我所做的,即将 a 放在返回类型const前面iterator。正如我在帖子中所述,这会触发第二个 Clang-Tidy 警告。

(2) 不消除 Clang-Tidy 警告。我也不确定我是否可以在作业的限制下使用它。

另外,这是一个最小的可重现示例:

class Iterator {
    ptr_type ptr; // whatever your pointer type is …
Run Code Online (Sandbox Code Playgroud)

c++ operator-overloading clang-tidy

5
推荐指数
1
解决办法
950
查看次数

将字符串与 Java/Kotlin 中等效但不同的 Unicode 代码点进行比较

我在使用不同编码器比较两个字符串时遇到了问题。我的代码实际上是用 Kotlin 编写的,但它在 JVM 上运行,并且有效地使用了 Java 的 String 实现。另外,我的问题具有更普遍的性质,我的实际代码不会受到关注。

\n

问题是我有两个字符串,比如说ab,其中

\n
a = "something something \xc3\xa4\xc3\xb6\xc3\xbc something"\nb = "\xc3\xa4\xc3\xb6\xc3\xbc"\n
Run Code Online (Sandbox Code Playgroud)\n

您期望a.contains(b)返回true,如果您像上面所示检索字符串,情况就是如此。但就我而言,字符串来自不同的来源,并且碰巧有不同的编码器。Stringa有编码器1,即UTF16,并且 Stringb有编码器0,即LATIN1。在这种情况下,a.contains(b)返回 false。现在您可能已经注意到我包含了特殊字符(\xc3\xa4\xc3\xb6\xc3\xbc),因为根据我的调试,这就是比较失败的地方。

\n

当我位于a.contains(b)发生调用的堆栈帧时,两个字符串都正确显示在我的调试器 (IntelliJ IDEA Ultimate 2020.2) 中。但是,如果我随后进入比较函数,我注意到在java.lang.StringLatin1.regionMatchesCI_UTF16()字节数组逐字符转换回的位置,特殊字符b现在不正确(\xc3\xa4-> a\xc3\xb6-> o\xc3\xbc-> u)。当然,这样比较就失败了。

\n

现在正如我所说,两个字符串最初都在调试器中正确显示,因此信息必须位于某处。我的问题是:我必须做什么才能让呼叫按预期a.contains(b) …

java string contains character-encoding kotlin

1
推荐指数
1
解决办法
1571
查看次数