Flutter便捷功能插件conveniently的使用

发布于 1周前 作者 gougou168 来自 Flutter

Flutter便捷功能插件conveniently的使用

标题

Flutter便捷功能插件conveniently的使用

内容

写Dart代码更方便。

这是一个很小的包,提供了你可能经常使用的非常方便的工具。

conveniently pub package

类型

类型

Result<V>

`Result`类型用于表示计算的结果。它可能是成功的(`Ok`实例)或失败的(`Fail`类型)。

它帮助强制错误检查,因为调用返回`Result`的函数的调用者必须检查返回值以处理错误,而不是像`Exception`那样。

你通常通过调用`catching`或`catching$`来获得`Result`(见页面末尾更多示例)。

final result = catching$(() {
  // 运行可能抛出异常的计算
});

// 模式匹配以处理结果 Object value = switch (result { Ok(value: var v) => v, Fail() => ‘error’ };

你也可以通过调用其工厂方法创建`Result`:

Result<String> result;
result = Result.ok('yes');
result = Result.fail(FormatException());

要更改`Result<V>`类型的类型,请使用其`map`或`flatMap`函数。

如果映射函数抛出异常,`map`和`flatMap`将返回一个带有`MappingFailureException`的`Fail`结果。

示例:

Result<int> result = Result.ok('yes').map((s) => s.length);

高级函数

高级函数

  • timing - 异步计时计算。
  • timing$ - 同步计时计算。
  • catching - 强制错误处理(异步)。
  • catching$ - 强制错误处理(同步)。
  • alwaysTrue - 总是返回`true`的谓词函数。
  • alwaysFalse - 总是返回`false`的谓词函数。

上述谓词函数非常有用,作为默认参数值,因为Dart不允许为默认参数值声明lambda。

`catching`函数返回一个`Result<T>`且永不抛出,这迫使调用者处理错误。

扩展函数

扩展函数

on <T>(任何类型,包括可空类型)

  • vmap - 映射任意值。
  • apply - 调用给定接收器函数,返回接收器(异步)。
  • apply$ - 调用给定接收器函数,返回接收器(异步)。

这特别方便捕获字段,例如在以下情况下:

class Person {
  final String? name;
  const Person(this.name);

// 不编译! // @override toString() { // 如果name是null,则返回’<No name>’; // 即使name是final,子类型可以将其转换为可变getter。 // return name.capitalize(); // }

@override toString() { // 使用vmap和apply着侧效应函数 return name?.vmap((n) => n.capitilize()).apply(print) ?? ‘<No name>’; } }

on <t?>(任何可空类型)

  • vmapOr - 如果非空,则映射值,否则提供默认值。
  • orThrow - 获取非空值,否则抛出错误。

`orThrow`存在是因为Dart不允许这样做:

Object? nullableValue = null;

// 在Dart中,这是可以的: final someValue = nullableValue ?? ‘yes!’;

// 缺失Dart功能性 - 不编译 final value = nullableValue ?? throw Exception(‘a good error message here’);

// 或Throw操作符也做了这一点,但不为最终用户给出好的错误信息。 final nonNullValue = nullableValue!;

// orThrow拯救了 final aValue = nullableValue.orThrow(() => ArgumentError(‘missing something’, ‘value’));

on int

  • times - 异步运行某些动作N次。
  • times$ - 同步运行某些动作N次。
  • timesIndex - 异步运行某些动作N次并带迭代索引。
  • timesIndex$ - 同步运行某些动作N次并带迭代索引。

async times函数接受一个可选的waitIterations参数,该参数决定了每个迭代是否等待前一个迭代完成再开始。默认情况下,waitIterationstrue。将其设置为false会导致所有迭代立即开始。

on bool Function(T)Future<bool> Function(T) (谓词)

  • not - 反转异步谓词。
  • not$ - 反转同步谓词。

示例

import 'package:conveniently/conveniently.dart';

/// Conveniently examples.
///
/// Functions whose name ends with '$' indicate they are "synchronous",
/// and dropping the '$' gives the corresponding async function's's name.
void main() {
  // do something N times
  3.times$(() =&gt; print('Conveniently'));

  // with an index
  2.timesIndex$((i) =&gt; print('Conveniently $i'));

  // map over any value
  print(10.vmap((i) =&gt; i + 1)); // prints 11

  // nullable helpers make it more like Optional
  Object? nullable;
  nullable = 'foo';
  print(nullable.vmapOr((v) =&gt; 'v = $v', () =&gt; 'none')); // prints 'v = foo'
  print(nullable.orThrow(ArgumentError.new)); // prints 'foo'
  nullable = null;
  print(nullable.vmapOr((v) =&gt; 'v = $v', () =&gt; 'none')); // prints 'none'

  // vmap and vmapOr help writing pipelines with nullable values
  nullable
      .vmapOr((s) =&gt; 'Some $s', () =&gt; 'default value')
      .vmap((v) =&gt; 'v not null here: ${v.hashCode}')
      .apply$(print) // use side-effect operations with apply/apply$
      .vmap(
          (s) =&gt; print(s.toUpperCase())); // prints 'V NOT NULL HERE: 305987627'

  // `not` can be used to negate a predicate
  bool isEven(int n) =&gt; n % 2 == 0;
  final isOdd = isEven.not$;
  print([1, 2, 3, 4].where(isOdd)); // prints (1, 3)

  // convert Exceptions to values to enforce error checking
  final result = catching$(() =&gt; 'function that may throw');

  // pattern match to get a value out of Result
  print(switch (result) {
    Ok(value: var v) =&gt; 'Success: $v',
    Fail(exception: var e) =&gt; 'FAILURE: $e',
  });

  // or use the getters
  print('Result is error? ${result.isError}, '
      'success: ${result.successOrNull}, '
      'failure: ${result.failureOrNull}');
}

更多关于Flutter便捷功能插件conveniently的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter便捷功能插件conveniently的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


在Flutter开发中,有许多便捷功能插件可以帮助开发者快速实现一些常见功能,从而提高开发效率。conveniently 这个词虽然不是一个具体的插件名称,但我们可以理解为寻找和使用那些能便捷地实现功能的插件。下面我将展示几个常用的Flutter插件及其代码示例,这些插件可以大大简化开发工作。

1. provider 插件 - 状态管理

provider 插件是Flutter中非常流行的状态管理解决方案之一,它允许你在组件树中方便地共享和监听数据。

安装

dependencies:
  provider: ^6.0.0

使用示例

import 'package:flutter/material.dart';
import 'package:provider/provider.dart';

void main() {
  runApp(
    MultiProvider(
      providers: [
        ChangeNotifierProvider(create: (_) => Counter()),
      ],
      child: MyApp(),
    ),
  );
}

class Counter with ChangeNotifier {
  int _count = 0;

  int get count => _count;

  void increment() {
    _count++;
    notifyListeners();
  }
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: Text('Flutter Provider Demo')),
        body: Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              Text(
                'You have pushed the button this many times:',
              ),
              Text(
                '${Provider.of<Counter>(context).count}',
                style: Theme.of(context).textTheme.headline4,
              ),
            ],
          ),
        ),
        floatingActionButton: FloatingActionButton(
          onPressed: () {
            Provider.of<Counter>(context, listen: false).increment();
          },
          tooltip: 'Increment',
          child: Icon(Icons.add),
        ),
      ),
    );
  }
}

2. shared_preferences 插件 - 数据存储

shared_preferences 插件允许你在Flutter应用中轻松地存储和检索简单的键值对数据。

安装

dependencies:
  shared_preferences: ^2.0.6

使用示例

import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  String _counterValue = '0';

  @override
  void initState() {
    super.initState();
    _readCounter();
  }

  Future<void> _readCounter() async {
    SharedPreferences sharedPreferences = await SharedPreferences.getInstance();
    setState(() {
      _counterValue = sharedPreferences.getString('counter') ?? '0';
    });
  }

  Future<void> _incrementCounter() async {
    SharedPreferences sharedPreferences = await SharedPreferences.getInstance();
    int counter = int.parse(_counterValue) + 1;
    await sharedPreferences.setString('counter', counter.toString());

    setState(() {
      _counterValue = counter.toString();
    });
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('SharedPreferences Demo'),
        ),
        body: Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              Text(
                'You have pushed the button this many times:',
              ),
              Text(
                _counterValue,
                style: Theme.of(context).textTheme.headline4,
              ),
            ],
          ),
        ),
        floatingActionButton: FloatingActionButton(
          onPressed: _incrementCounter,
          tooltip: 'Increment',
          child: Icon(Icons.add),
        ),
      ),
    );
  }
}

3. url_launcher 插件 - 打开URL

url_launcher 插件允许你的Flutter应用打开网页URL。

安装

dependencies:
  url_launcher: ^6.0.3

使用示例

import 'package:flutter/material.dart';
import 'package:url_launcher/url_launcher.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('URL Launcher Demo'),
        ),
        body: Center(
          child: ElevatedButton(
            onPressed: _launchURL,
            child: Text('Open Flutter Website'),
          ),
        ),
      ),
    );
  }

  _launchURL() async {
    const url = 'https://flutter.dev';
    if (await canLaunch(url)) {
      await launch(url);
    } else {
      throw 'Could not launch $url';
    }
  }
}

这些示例展示了如何使用Flutter中的几个流行插件来简化开发过程。当然,Flutter社区中有许多其他有用的插件,涵盖了从网络请求到图像处理的各个方面。选择合适的插件可以显著提高开发效率和应用的功能丰富度。

回到顶部