XCoderLiu's Blog

An iOS developer @ Tencent

吾生也有涯,而知也无涯!


我的 Github

Dart语法初窥

今天稍微体验了下 Dart 毕竟2020年了,Flutter 终于迎来了第一个 stable 版本。我学习 Flutter 还是喜欢从语言层面慢慢展开学习,贴一下 dart 官方学习网站。 不在这儿详细讲每个语法细节,只讲我对比 swift c++ 或者 objective-c 的语法中看到的一些好玩的东西。

Mixins

Mixins with official

首先说说这个,它是我看介绍里面一眼没法看懂的东西。

Look at this!

// Mixins are a way of reusing a class’s code in multiple class hierarchies.
// To use a mixin, use the with keyword followed by one or more mixin names. 
// The following example shows two classes that use mixins:

class Musician extends Performer with Musical {
  // ···
}

class Maestro extends Person
    with Musical, Aggressive, Demented {
  Maestro(String maestroName) {
    name = maestroName;
    canConduct = true;
  }
}

这是官方的详细介绍,解释的第一行用来解决 dart 多继承,实际上大多数语言都是单继承,我见到的除了 c++ 。看到这儿我脑海里扑面而来的感觉是这是 swift 和 objective-c 的 Protocol 么?

// To implement a mixin, create a class that extends Object and declares no constructors. 
// Unless you want your mixin to be usable as a regular class, use the mixin keyword instead of class. 
// For example:

mixin Musical {
  bool canPlayPiano = false;
  bool canCompose = false;
  bool canConduct = false;

  void entertainMe() {
    if (canPlayPiano) {
      print('Playing piano');
    } else if (canConduct) {
      print('Waving hands');
    } else {
      print('Humming to self');
    }
  }
}

// To specify that only certain types can use the mixin — for example, 
// so your mixin can invoke a method that it doesn’t define — use on to specify the required superclass:

mixin MusicalPerformer on Musician {
  // ···
}

That is all! WFT???

wtf

Talk is cheap, show me your code!

1.手写我写了 ABCDEF 这几个类,然后我开始乱用继承了哈哈哈,然后我摸索出这个玩意儿真的很像 协议,但是使用它需要具备一定条件

  • Derived from a class declaration.
  • Applied to a superclass to create a new class.
  • May be derived from class with super-class, then application must be on class implementing super-class interface.
  • May have super-invocations if the mixin class has a super-class.
  • Cannot have generative constructors.
  • Mixin application forwards some constructors.

补充一下 mixin 关键字的只能继承自 object 不能由别的类派生,这个 change log 好像不包含这条。看到没有构造函数,然后可以用超类的方法中实现,invoke 当前类,我觉得这好像稍微比协议更多了点玩意儿:

B 继承自 AC 继承自 B, E,F 我写作 mixin 类型,然后 class C extends B with F 这样编辑器会报错。

error

为啥呢? mixin on 好像就是一个协议建立在另一个协议的基础上,实现的人必须要实现 on 的协议,我尝试了下两种方式编译器都可以通过:

  1. C 自己实现 E:
class A {
  bool a = true;
}

class B extends A {
  bool b = true;
}

class C extends B with E, F {
  bool c = true;
}

class D {
  bool d = true;
}

mixin E {
  bool e = true;
}

mixin F on E {
  bool f = true;
}

2.父类 B 实现 E:

class A {
  bool a = true;
}

class B extends A with E {
  bool b = true;
}

class C extends B with F {
  bool c = true;
}

class D {
  bool d = true;
}

mixin E {
  bool e = true;
}

mixin F on E {
  bool f = true;
}

各位看官到这儿,想必大家内心有一种懵懂的想法,大家就各自想吧。另外 把 E 和 F 的 mixin 改成 class 这样他们就可以有构造函数可以构建实例了。

Spread operator (…)

…这个操作符可以用来表示一个列表全部元素:

var list = [1, 2, 3];
var list2 = [0, ...list];
assert(list2.length == 4);

如果 list 可能为空我们还可以加个 (swift 的味道,香):

var list;
var list2 = [0, ...?list];
assert(list2.length == 1);

Collection if

你可以在集合类型中添加 if 条件判断:

var nav = [
  'Home',
  'Furniture',
  'Plants',
  if (promoActive) 'Outlet'
];

是不是很神奇,这样写 UI 就很嗨了,比如你要写个翻页的页面,但是最后一页可以不要加上 Next button:

Widget build(BuildContext context) {
  return Column(children: [
    Text(mainText),
    if (page != pages.last)
      FlatButton(child: Text('Next')),
  ]);
}

Collection for

你可以在集合类型中添加 for 遍历添加:

Widget build(BuildContext context) {
  return Column(children: [
    Text(mainText),
    for (var section in sections)
      HeadingAction(section.heading),
  ]);
}

End

All this ,我看到 Dart 之所以是 Dart, 首先是因为它是 Flutter 的官方语言吧。

最近的文章

Flutter InheritedWidget

赘述学习 Flutter 之后有两个很重要的概念,StatefulWidget 和 StatelessWidget,其中 Stateful 其实指的就是需要要数据的 UI 并且会根据数据进行调整,也是程序开发中最为常见的状态,比较数据驱动 UI 显示。Stateless 是不需要记录状态的 Widget,一个静态的不需要根据数据做调整的 UI。而今天讲到另一个类型的 Widget,Inherited Widget 他并不能以大多数面向对象编程语言中的继承来理解。InheritedWidge...…

Flutter继续阅读
更早的文章

Yosemites dark mode

检查Dark模式的代码如下:NSDictionary *dict = [[NSUserDefaults standardUserDefaults] persistentDomainForName:NSGlobalDomain];id style = [dict objectForKey:@"AppleInterfaceStyle"];BOOL darkModeOn = ( style && [style isKindOfClass:[NSString class]] &am...…

OSX继续阅读