【CSDN 编者按】同受 Google 支持,一个是其官方开发的语言——Dart,一个被扶持为 Android 开发的官方语言——Kotlin。放在一起看,Kotlin 对比 Dart 的优越性远不止更安全这么简单,本文作者罗列出 13 个理由。

作者 | Joel

译者 | 弯月        责编 | 屠敏

出品 | CSDN(ID:CSDNnews)

我非常喜欢 Flutter,我认为它是开发高质量多平台应用的最佳选择之一,然而,我却不怎么喜欢 Dart(编写 Flutter 的语言)。为什么?和 Kotlin 相比,原因如下。

没有 null 安全

我知道这个问题近期就能得到解决(https://dart.dev/null-safety),但目前我们仍然需要面对。2018 年,Dart 首次发布的时候(我指的是 Dart 2),就没有 null 安全,太不应该了。

没有数据类

数据类的主要目的是保存数据。在数据驱动开发模型中,数据类就是值对象,而且在适当的语言支持下,不可变的数据类型非常方便函数式编程。

Kotlin 有下面这样的支持:

data class User(val name: String, val age: Int)val user1 = User(name =“John”, age = 30)val user2 =user1.copy(age = 20)

即便不考虑复制(和相等比较)功能的实现,Dart 的写法也非常冗长:

class User {User({this.name,this.age});final String name;final int age;
}final user1 = User(name: ‘John’, age: 30);
final user2 = User(name: user1.name, age: 20);

而且 Dart 还缺少 Kotlin 提供的某些功能。例如,在 Kotlin 中,你可以将这些参数作为位置参数或命名参数进行传递(甚至可以混合使用:val user = User('John', age = 30)),而在 Dart 中,位置或名称,你只能选择其一(但是它们是可选的,默认为 null)。

有一个很好的包 build_value,可以解决深度相等性检查和生成复制方法的问题,我们经常在代码库中使用这个包,但这不是理想的解决方案。

首先,与 Kotlin 版本相比,Dart 需要一些样板代码:

abstract class User implements Built<User, UserBuilder> {User._();factory User([voidFunction(UserBuilder) updates]) = _$User;String get name; int getage;
}final user1 = User((b) => b ..name = ‘John’ ..age = 30);
final user2 = user1.rebuild((b) => b..age = 20);

其次,Dart 缺乏一些功能,比如没有简单的方法让编辑器在编译期间检查必须参数是否传递。

Dart 能够提供数据类的支持吗?可能会,但近期内还不行。

没有密封类

我们经常使用的 Kotlin 的另一个功能是密封类。从本质上讲,密封类表示了一种受限的类层次结构:值只能是有限的几种类型中的一种。与枚举不同,这个值不是 singleton,而是一个适当的类,可以拥有多个不同状态的实例。

为什么密封类很实用?我们来看一个很常见的例子:

sealed class Result<out VALUE> {data class Error(valerror: Throwable) : Result<Nothing>()data classSuccess<VALUE>(val value: VALUE) : Result<VALUE>()
}fun process(result: Result<String>): String = when(result) {is Result.Error ->“Error: ${result.error}”is Result.Success ->“Success: ${result.value}”
}

用这个方法来代替异常处理很不错:它并不是去捕获异常(因为有时候会忘记捕获异常),而是强迫使用者处理结果,结果可能是错误的或正确的(在许多函数式语言和库中该类型被称为 Either)。不仅你需要考虑可能出现的错误,而且 Kotlin 也会提供一些很好的功能。你看,when 分支中有类型转换吗?你不需要进行类型转换,因为 Kotlin 很聪明,会自动进行转换。

那么 Dart 呢?我们希望有一天 Dart 也能提供这些功能。

枚举不支持自定义值

有时,我们需要在枚举中添加一些值。Kotlin 的写法很简单:

enum class Level(val value: Int) {INFO(10),WARNING(20),ERROR(30)
}val value = Level.WARNING.value

Dart 没有类似的功能。但你可以使用扩展:

enum Level {info,warning,level
}extension LevelValue on Level {int get value {switch(this) {case Level.info:return 10;case Level.warning:return 20;case Level.level:return 30;}}
}final value = Level.warning.value;

首先,这段代码太冗长了;其次,请参照下面这一点。

编译器不够智能

前面的示例给出了如下警告:

This function has a return type of ‘int’, butdoesn’t end with a return statement. Try adding a return statement, or changingthe return type to ‘void’.

什么意思?Level 枚举只有 3 个选项,而且都列出来了。该函数不可能返回 void。我不想添加 default 语句(否则,如果我在枚举中添加了另一个选项,但忘记了更新扩展,就可能会返回错误的结果)。出于相同的原因,我不想忽略这个警告。我希望当且仅当所有选项都不匹配的时候报错,而 Kotlin 就是这么做的。

没有 singleton

如何在Kotlin中定义singletons?很简单:object Singleton。Dart有类似的东西吗?最简单的写法可能是:

class Singleton {const Singleton._();factory Singleton()=> const Singleton._();
}

当然,这也没什么大不了,但是如果你必须针对每种情况重复编写上述代码,那么工作量就大了。在 Kotlin 项目中,我们经常使用 singletons,例如作为密封类的“常量”等等,但 Dart 中连密封类都没有。

没有 switch / if / try 表达式

还记得在讨论 Dart 没有密封类时,我们提到的示例吗?虽然没有关键字 return,但函数仍然会返回字符串。这有可能要归功于两个方面:

  • fungetAnswer(): String = "42"  等价于 fun getAnswer(): String { return "42" }。在 Dart 中,你甚至只需编写 StringgetAnswer() => '42';

  • when 是一个表达式:这意味着你可以返回 when 的结果,并且编译器足够聪明,可以推断出正确的类型,因为每个条件分支都会返回 String。

这不仅仅是语法简洁性的问题,编译器返回 when,是为了强迫我们提供所有的选项(比如对于枚举或密封类,你必须指定所有选项或使用 else 语句)。

没有关键字 protected

为了私有化方法(或变量),我们需要在其名称前添加下划线。然而,当你需要从允许的范围之外访问该方法时,就会遇到编译错误。

为了保护某个方法,你可以使用 meta 包中的 @protected 注释。但是,你会收到静态分析的警告。

Dart 不支持 protected,所以要么是 public,要么是 private,不能折中。

没有类型别名

 

实际上,Dart 中有类型别名,但仅适用于函数类型。

你可以编写如下代码:

typedefFormatDate = String Function(DateTime);

但是不能写:

typedefJson = Map<String, dynamic>;

如果你的项目需要使用 json,就要在代码中书写大量的Map<String, dynamic>。

也许,有一天 Dart 会解决这个问题吧……

没有简洁的语法

你可能想说:“既然你已经习惯了 Kotlin 的语法,为什么不直接使用 Kotlin?为什么还要用 Dart?”

没错,我是很喜欢 Kotlin 的语法,但不仅仅是因为我习惯了。在 Kotlin 中编写 lambda 语法非常简洁,比如 listOf(1, 2, 3).map {it.toString() },远胜于[1,2,3].map((i) => i.toString());。如果遇到很多行的 lambda(或者 lambda 链),Dart 的书写就会非常复杂。甚至还需要分号……

没有嵌套类/扩展

我非常希望 Dart 能支持嵌套类。比如我们想做一些消息处理:

abstract class Translations {static abstract classCommon {static String yes =‘Yes’;static String no =‘No’;}static abstract classAuth {static String logIn =‘Log in’;static String logOut =‘Log out’;}
}final message = Translations.Auth.logIn;

没有恰当的泛型协变

在 Dart 的类型中,泛型类中的变量是协变的。这有什么不好?因为这种方法无异乎自讨苦吃。我们来看一个例子:

class Animal {}class Dog extends Animal {}class Cat extends Animal {}void main() {List<Animal>animals = [Dog()];List<Cat> cats =[];cats.add(animals.first);
}

虽然可以通过编译,但是运行的时候会出错:TypeError: Instance of 'Dog': type 'Dog' is not a subtype of type'Cat'。

如果在 Kotlin 中尝试这样的小把戏:

abstract class Animalclass Dog : Animal()class Cat : Animal()fun main() {val animals =listOf<Animal>(Dog())val cats =mutableListOf<Cat>()cats.add(animals.first())
}

编译都不过去,它会直接报错:Type inference failed. Expected type mismatch: inferred type isAnimal but Cat was expected。

没有 final 类

《Effective Java》这本书中说:“继承必须经过设计,并通过文档说明,否则就不该使用。”因此,在 Java 中,我们应该尽量使用 final 类。

Kotlin 则更进一步,默认情况下所有类都是 final。那么,Dart 呢?我们根本没办法指定 final 类,没办法禁止继承。

Dart 真的“一文不值”?

虽然上面我罗嗦了一大堆 Dart 的不足,但 Dart 也有一些我非常喜欢的优点:

  • 类声明本身就是接口。每个类都定义了一个由 public 成员组成的接口。因此,你只需 implement 类,并提供重载功能:在测试中模拟实现。

  • 无类型擦除。与Kotlin不同,List <String>在运行时仍然是List<String>。

  • 最后,很重要的一点:Dart 仍在不断发展中。我们有扩展程序,也许很快就能获得 null 安全。

希望有一天,本文所提及的不足都能得到改善,Dart 能够成为一门安全的现代编程语言。

原文链接:https://medium.com/codex/13-reasons-why-dart-is-worse-than-kotlin-eba93dfedd8

声明:本文为 CSDN 翻译,转载请注明来源。

☞三年白干!程序员孙某因违反《竞业协议》赔偿腾讯 97.6 万元,返还 15.8 万元☞CTO 写低级 Bug,致公司 70 GB 数据遭泄露!
☞再见!经典版Edge!
☞Google 重磅发布 Flutter 2 !一套代码横扫 5 大系统

Dart 语言不如 Kotlin?这里列了 13 个原因相关推荐

  1. 给Java开发者的Flutter开发基础---Dart语言

    接近半年没有在简书冒泡了.这段时间一是忙于使用云信IM开发相应项目,二是整理和收集相关Flutter的相关资料进行学习.国内关于Flutter的资料还是太过于稀少,以至于我只能去YouTube和Ude ...

  2. dart 语言是jvm_Dart编译技术在服务端的探索和应用

    前言 最近闲鱼技术团队在Flutter+Dart的多端一体化的基础上,实现了FaaS研发模式.Dart吸取了其它高级语言设计的精华,例如Smalltalk的Image技术.JVM的HotSpot和Da ...

  3. Dart语言精简入门介绍

    Dart语言精简入门介绍 1.介绍 Dart 在设计时应该是同时借鉴了 Java 和 JavaScript和kotlin 面向对象 JIT&AOT:JIT(Just in Time)优点:即时 ...

  4. dart参数传方法_Flutter必备Dart语言快速入门

    作为Flutter专属的开发语言(当然Dart不知如此,也可以开发Web和服务端),面对对象.高性能.多端一致.热更新是Dart的优势所在,是Flutter开发必须掌握的语言,也正是Flutter的流 ...

  5. dart 语言中的列表(List)

    dart 语言中的列表(List) 作者: 李俊才 邮箱 :291148484@163.com CSDN 主页:https://blog.csdn.net/qq_28550263?spm=1001.2 ...

  6. flutter基础 dart语言学习笔记

    1.JIT(Just-In-Time 动态编译) 即时编译为什么能大幅度提升性能 JIT,即Just-in-time,动态(即时)编译,边运行边编译: https://book.flutterchin ...

  7. Fluter基础巩固之Dart语言详解一

    在上一篇https://www.cnblogs.com/webor2006/p/11367345.html中咱们已经搭建好了Flutter的开发环境了,而Flutter的开发语言是选用的dart,那么 ...

  8. 给 Android 开发者的 Dart 语言基础

    本文基于官方的文档,整理出 Dart 语言中与 Java 和 Kotlin 语言类似和特有的部分,因此本文的读者需要具备一定的 Java 及 Kotlin 语言基础,相信大家读完本文就可以看懂大部分的 ...

  9. Dart语言——45分钟快速入门(上)

    文章目录 前言 视频课程 环境准备 安装Dart SDK 配置环境变量 配置 VSCode 编辑器 测试环境 基础语法 代码注释 内置数据类型 变量与常量 定义变量 定义常量 内置类型的常用操作 数值 ...

最新文章

  1. 关于Windows Message ID 以及应用【转】
  2. oracle经典书籍推荐
  3. 怎么判断日出时间早晚_珠海最全防堵攻略,知道这些上班时间或缩短半小时!有大数据分析!...
  4. cass批量选目标快捷键_大神总结100个CAD快捷键+20个CAD制图技巧,值得收藏!
  5. Android—TableLayout自定义表格
  6. vue完全编程方式与react在书写和运用上的异同
  7. java程序员编程过程中的基本问题
  8. python的特性是_python的特性
  9. android dialog 隐藏状态栏_Flutter-最近搞了个项目-启动页Splash,Navigator.pop无法关闭Dialog...
  10. 使用 MyEclipse远程调试 Java 应用程序
  11. AlphaGo实力远超对手
  12. 房友系统服务器地址,房友系统的那些功能,你都知道吗?
  13. 华为商业级AC6005+AP3030DN无线WIFI组网
  14. Ebbinghaus English Memory ( 艾宾浩斯英语记忆 ) 程序 之 设计思路 与 代码实现
  15. 基于springboot老年人健康体检系统(带论文)
  16. 将文件夹下的多个文件的内容合并到一个文件中
  17. 关于前端接口报错500原因
  18. 【NLP】一种自写的分词算法-中文基于字,英文基于单词,支持自定义字典
  19. 【算法】几个数组拆分题的算法(动态规划,矩阵递归和同余问题)
  20. python异常处理

热门文章

  1. 敏捷开发绩效管理之七:敏捷开发生产率(下)(简化功能点分析,NESMA,两级简化)...
  2. VC2008中使用GDI+(转)
  3. hdu 1281棋盘游戏(二分匹配)
  4. Android 发送HTTP GET POST 请求以及通过 MultipartEntityBuilder 上传文件
  5. 【PHP+MySQL学习笔记】php操作MySQL数据库中语句
  6. 1.VBA实现EXCEL中Sheet1的 甲列 相同数值的行对应的乙列的数的和作为Sheet2中丙列中与Sheet1中甲列 相同的行对应的丁列的值...
  7. CSS光标属性一览表
  8. 显卡显存故障检测工具_为RTX30系显卡做准备,骨伽GEX750金牌全模组电源装机体验...
  9. 【剑指Offer】青蛙跳台阶问题
  10. python写gui、主体程序必须放进函数里吗_Python学习(二):使用TKinter进行GUI程序设计...