Kotlin允许扩展现有types是否好?

Kotlin能够扩展现有的types。 例如,我们可以这样做 :

fun String.replaceSpaces(): String { return this.replace(' ', '_') } val formatted = str.replaceSpaces() 

但是, 这是一个反模式 。

Kotlin是否回避了在Javascript中导致的问题?

不,这不是一个反模式。 在JS中它是一个反模式,因为JS是动态的 ,因此改变一个原型改变了代码在运行时的工作方式使其成为一个反模式。 根据in运算符的工作原理,这也是非常危险的,并且基于可以重写所有内容的事实,因此更改原型可能会影响页面某处的代码:

 Number.prototype.toString = function(){ return "bullshit"; }; alert(""+12); 

在kotlin中,情况并非如此,因为kotlin是静态的 ,所有引用都是在编译时建立的 。 此外,你不能覆盖现有的方法,所以它不是危险的。

几种语言已经有了。 正如链接的答案中所述,JavaScript的问题是它的工作方式。

除了我的头顶,JavaScript有一个重写属性的方法。 一个库可以很好地定义一个覆盖,但另一个覆盖它再次。 从两个库中调用的函数,全部都是乱七八糟的。

我认为这更多的是一个types系统和可见性问题。

展开欢迎:)

你不能比较JS和Kotlin这样的原型语言。 所有扩展都是静态解析的, 不要修改扩展types(“receiver”)。 这真的很重要,并使您的担心无效。 请查看文档以了解更多关于在后台使用扩展名(编译器)发生的事情。

恕我直言 ,你需要谨慎扩展。 不要让Kotlin项目中的每个开发人员都向随机types添加新的扩展。 我认为项目必须定义一些规则来处理在现有types上定义新的函数/属性的过程,因为否则就很难读取外部代码。 还应该有坚定的地方放置这些扩展。

而不是在StackOverflow上提出问题,你应该编译这个例子,并看到生成的代码。 一切都会变得清晰:

 function replaceSpaces($receiver) { return replace($receiver, 32, 95); } function foo(str) { var formatted = replaceSpaces(str); } 

根本没有猴子补丁! 扩展函数只是Kotlin中的一个语法糖。 这只是将第一个parameter passing给静态函数的另一种方法。