Dart:枚举支持成员属性,并不好用

4,491 阅读4分钟

本文正在参加「金石计划 . 瓜分6万现金大奖」

前言

我之前写过2篇文章:

UI = f(State),在Swift中的一点思考

Flutter:枚举的缺点

一来阐述了所谓状态构建UI的重要性,同时也吐槽了作为以状态构建UI的Flutter在枚举方面缺点,无法带入参数,导致无法将状态和数据同时去驱动页面。

这不Dart2.17不就支持枚举支持成员属性,我这一年都在做原生开发,很久没有做Flutter开发的我而言,最近体验了一下这个功能。

对比Swift,说说我使用的感受。

当然,Dart与Swift本身就是两门语言,大家权当是我自己吐槽娱乐。

枚举支持成员属性,过于死板,不够灵活

我们先来看看一个Dart的例子:

enum Water {
  frozen(0),
  lukewarm(40),
  boiling(100);

  final int temperature;
  const Water(this.temperature);
}

一旦支持成员属性,每一个枚举都必须带参数

其实很多时候,并不是每个枚举状态都需要带入参数,

比如上面的例子,我想加一个hot状态,但是hot状态我并不想明确具体温度,但是这么定义是不行的:

image.png

温度非加不可,不加就报错。

可以将final int temperature;改写成为final int? temperature;,将hot状态改成hot(null),但怎么看,都觉得怪怪的。

对比Swift,这个简直是小case:

enum Water {

  case frozen(Int)

  case lukewarm(Int)

  case boiling(Int)

  case hot

}

成员属性无法修改

大家都知道,水的沸点在不同的气压下面就有所不同,所以上面这个boiling(100)过于理想。

于是乎我想这么创建一个变量:

var status = Water.boiling(98);

然而,现实却是:

image.png

枚举可以带参,但是不能改变参数的状态,这点和Swift比,却是过于死板了:

let status = Water.boiling(98)

单就对比这两点,我就对于Dart的枚举就无感了,虽然有了支持成员属性的这个功能,但是离我想要的功能,还有很远,诸如写出下面这样的枚举状态,还是无法实现:

enum ResponseState {

    case loading

    case success(ResponseStateSuccess)

    case error

    enum ResponseStateSuccess {

        case hasContent

        case empty

    }
}

最后勘误一下自己之前文章里面的错误:

Kotlin不用多说,Swift有的,它都有,枚举中传参也是家常便饭,枚举编写的方式几乎和Swift一模一样。

特地去看了Kotlin的教程,发现Kotlin的枚举与Dart如出一辙,在这两种语言中,枚举都是一个class!

Kotlin的枚举:

enum class Color(val rgb: Int) {
    RED(0xFF0000),
    GREEN(0x00FF00),
    BLUE(0x0000FF)
}

有兴趣的同学可以看看Dart的源码,在/core/enum.dart文件。

顺带说明一下Dart空安全,解包也非常不好用

另外Dart虽然对于空安全做了支持,对于我们编写代码的时候,我们需要严谨的定义属性,这点当然是好事,但是在解包的时候,就让人有点跪了。

比如下面这段代码:

class Person {
  String? firstName;

  String? lastName;

  Person(this.firstName, this.lastName);

  String? get fullName {
    if (firstName != null && lastName != null) {
      return lastName! + firstName!;
    } else {
      return null;
    }
  }
}

firstName和lastName都是可选类型,我只能通过!= null对其做了判空处理,在进行拼接的时候,我也只能通过!对做强制解包进行运算,然后在if条件语句中我已经通过!= null保证了变量不可能为空,但是如果和Swift与Kotlin的判空与解包比起来,Dart的书写体验真的的是太差了。

class Person {

    var firstName: String?

    var lastName: String?

    var fullName: String? {
        /// Swift 5.7之前
        if let firstName = firstName, let lastName = lastName {
            return firstName + lastName
        } else {
            return nil
        }

        /// Swift 5.7之后
        if let firstName, let lastName {
            return firstName + lastName
        } else {
            return nil
        }
    }
}

总结

怎么说呢,有总比没有好。

Dart这个枚举支持成员属性对于静态值的支持还是不错,能少写一些代码就少写一点。

同时,将两门不同的语言这样进行对比也不算友好,就好像拿一方的短处去对比另一方的长处一样。毕竟Dart优势是少有既能JIT又能AOT编译的语言,总不能要求面面俱到吧?

我也希望Dart能越来越好啦,这样一份逻辑我就可以无缝CV啦。

参考文档

Kotlin 枚举类

自己写的项目,欢迎大家star⭐️

RxStudy:RxSwift/RxCocoa框架,MVVM模式编写wanandroid客户端。

GetXStudy:使用GetX,重构了Flutter wanandroid客户端。

本文正在参加「金石计划 . 瓜分6万现金大奖」