Dart 语言不如 Kotlin?这里列了 13 个原因
【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 个原因相关推荐
- 给Java开发者的Flutter开发基础---Dart语言
接近半年没有在简书冒泡了.这段时间一是忙于使用云信IM开发相应项目,二是整理和收集相关Flutter的相关资料进行学习.国内关于Flutter的资料还是太过于稀少,以至于我只能去YouTube和Ude ...
- dart 语言是jvm_Dart编译技术在服务端的探索和应用
前言 最近闲鱼技术团队在Flutter+Dart的多端一体化的基础上,实现了FaaS研发模式.Dart吸取了其它高级语言设计的精华,例如Smalltalk的Image技术.JVM的HotSpot和Da ...
- Dart语言精简入门介绍
Dart语言精简入门介绍 1.介绍 Dart 在设计时应该是同时借鉴了 Java 和 JavaScript和kotlin 面向对象 JIT&AOT:JIT(Just in Time)优点:即时 ...
- dart参数传方法_Flutter必备Dart语言快速入门
作为Flutter专属的开发语言(当然Dart不知如此,也可以开发Web和服务端),面对对象.高性能.多端一致.热更新是Dart的优势所在,是Flutter开发必须掌握的语言,也正是Flutter的流 ...
- dart 语言中的列表(List)
dart 语言中的列表(List) 作者: 李俊才 邮箱 :291148484@163.com CSDN 主页:https://blog.csdn.net/qq_28550263?spm=1001.2 ...
- flutter基础 dart语言学习笔记
1.JIT(Just-In-Time 动态编译) 即时编译为什么能大幅度提升性能 JIT,即Just-in-time,动态(即时)编译,边运行边编译: https://book.flutterchin ...
- Fluter基础巩固之Dart语言详解一
在上一篇https://www.cnblogs.com/webor2006/p/11367345.html中咱们已经搭建好了Flutter的开发环境了,而Flutter的开发语言是选用的dart,那么 ...
- 给 Android 开发者的 Dart 语言基础
本文基于官方的文档,整理出 Dart 语言中与 Java 和 Kotlin 语言类似和特有的部分,因此本文的读者需要具备一定的 Java 及 Kotlin 语言基础,相信大家读完本文就可以看懂大部分的 ...
- Dart语言——45分钟快速入门(上)
文章目录 前言 视频课程 环境准备 安装Dart SDK 配置环境变量 配置 VSCode 编辑器 测试环境 基础语法 代码注释 内置数据类型 变量与常量 定义变量 定义常量 内置类型的常用操作 数值 ...
最新文章
- 关于Windows Message ID 以及应用【转】
- oracle经典书籍推荐
- 怎么判断日出时间早晚_珠海最全防堵攻略,知道这些上班时间或缩短半小时!有大数据分析!...
- cass批量选目标快捷键_大神总结100个CAD快捷键+20个CAD制图技巧,值得收藏!
- Android—TableLayout自定义表格
- vue完全编程方式与react在书写和运用上的异同
- java程序员编程过程中的基本问题
- python的特性是_python的特性
- android dialog 隐藏状态栏_Flutter-最近搞了个项目-启动页Splash,Navigator.pop无法关闭Dialog...
- 使用 MyEclipse远程调试 Java 应用程序
- AlphaGo实力远超对手
- 房友系统服务器地址,房友系统的那些功能,你都知道吗?
- 华为商业级AC6005+AP3030DN无线WIFI组网
- Ebbinghaus English Memory ( 艾宾浩斯英语记忆 ) 程序 之 设计思路 与 代码实现
- 基于springboot老年人健康体检系统(带论文)
- 将文件夹下的多个文件的内容合并到一个文件中
- 关于前端接口报错500原因
- 【NLP】一种自写的分词算法-中文基于字,英文基于单词,支持自定义字典
- 【算法】几个数组拆分题的算法(动态规划,矩阵递归和同余问题)
- python异常处理
热门文章
- 敏捷开发绩效管理之七:敏捷开发生产率(下)(简化功能点分析,NESMA,两级简化)...
- VC2008中使用GDI+(转)
- hdu 1281棋盘游戏(二分匹配)
- Android 发送HTTP GET POST 请求以及通过 MultipartEntityBuilder 上传文件
- 【PHP+MySQL学习笔记】php操作MySQL数据库中语句
- 1.VBA实现EXCEL中Sheet1的 甲列 相同数值的行对应的乙列的数的和作为Sheet2中丙列中与Sheet1中甲列 相同的行对应的丁列的值...
- CSS光标属性一览表
- 显卡显存故障检测工具_为RTX30系显卡做准备,骨伽GEX750金牌全模组电源装机体验...
- 【剑指Offer】青蛙跳台阶问题
- python写gui、主体程序必须放进函数里吗_Python学习(二):使用TKinter进行GUI程序设计...