6

鉴于此代码:

val value = "something"

println(value.toUpperCase().toLowerCase() == value)   // prints true
println(value.toUpperCase().toLowerCase() === value)  // prints false

在 Kotlin/JVM 1.3.40 上,我得到:

true
false

在 Kotlin/JS 1.3.40 上,我得到:

true
true

我希望两者的结果相同,并且我希望 Kotlin/JVM 的整体结果(因为我应该有不同的String对象)。

为什么我会根据运行时环境得到不同的结果?

4

2 回答 2

4

这是因为运行时如何处理它。

在 JVM 上,==映射到equals===映射到==(身份检查),如此所述。同时,JavaScript 的等号运算符更奇怪。如果你反编译你的代码,你会用 JS 得到这个:

kotlin.kotlin.io.output.flush();
if (typeof kotlin === 'undefined') { 
    throw new Error("Error loading module 'moduleId'. Its dependency 'kotlin' was not found. Please, check whether 'kotlin' is loaded prior to 'moduleId'."); 
}
var moduleId = function (_, Kotlin) { 
    'use strict'; 
    var equals = Kotlin.equals; 
    var println = Kotlin.kotlin.io.println_s8jyv4$; 
    function main(args) { 
        var value = 'something';
        println(equals(value.toUpperCase().toLowerCase(), value)); // NOTE: equals
        println(value.toUpperCase().toLowerCase() === value);      // NOTE: ===
    } 
    _.main_kand9s$ = main; 
    main([]); 
    Kotlin.defineModule('moduleId', _); 
    return _; 
}(typeof moduleId === 'undefined' ? {} : moduleId, kotlin); 
kotlin.kotlin.io.output.buffer;

现在,如果您考虑等效的 Java 代码(稍微缩短并且没有 Kotlin):

public static void main(String[] args){
    String value = "something";

    System.out.println(value.toUpperCase().toLowerCase().equals(value));
    System.out.println(value.toUpperCase().toLowerCase() == value);
}

toUpperCase().toLowerCase()创建一个新对象,它打破了==比较,即身份检查

虽然===也被概述为身份检查,a === b但如果 a 和 b 是包含相同字符的字符串,则为真。从反编译的 Kotlin 代码中可以看出,Kotlin.JS 编译为原始字符串,而不是字符串对象。因此,===当您处理原始字符串时,in JS 将返回 true。

于 2019-07-01T12:21:40.183 回答
1

在 JavaScript 中,既有原始字符串也有字符串对象(参见https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String中的“字符串原语和字符串对象之间的区别” )。

value.toUpperCase().toLowerCase() === value在 Kotlin/JS 中编译为value.toUpperCase().toLowerCase() === value在 JavaScript 中(您可以通过查看https://try.kotlinlang.org/上的“生成的 JavaScript 代码”选项卡来验证)。value.toUpperCase().toLowerCase()返回一个原始字符串。===在原始字符串上是正常的相等。

于 2019-07-01T12:12:05.960 回答