Dart中一等函数与void函数的区别及GestureDetector的onTap赋值报错问题
问题解答
1. Dart中一等函数与void函数的区别
- 一等函数是Dart对函数类型的通用特性定义:所有函数都属于一等公民(也就是一等函数),支持作为变量赋值、作为参数传递、作为方法返回值,和函数的参数、返回值类型无关。
- void函数是返回值为void类型的函数,属于一等函数的子集,这类函数执行后没有可使用的返回值,Flutter的各类手势、UI事件回调大多要求该类型的函数,比如本次出现问题的
onTap要求的void Function(),就是典型的无参数、无返回值的void函数。
2. 报错原因
你定义的onPress参数类型是Function?,这是泛指所有可调用对象,可能携带任意数量、类型的参数,也可能有任意类型的返回值。而GestureDetector的onTap要求的参数类型是void Function()?,只能接受无参数、无返回值的函数,二者类型不匹配,Dart的静态类型校验不通过,因此抛出该错误。
3. 解决方法
可根据业务场景选择两种常用方案:
- 方案1:直接明确
onPress的类型为onTap要求的函数类型,也是最推荐的强类型写法
把final Function? onPress;修改为final void Function()? onPress;即可,修改后完整代码如下:
import 'package:flutter/material.dart'; class ReusableCard extends StatelessWidget { final Color colour; final Widget? childCard; final void Function()? onPress; // 此处修改参数类型 ReusableCard({required this.colour,this.childCard,this.onPress}) ; @override Widget build(BuildContext context) { return GestureDetector( onTap: onPress, child: Container( child: childCard, margin: EdgeInsets.all(15.0), decoration: BoxDecoration( color: colour, borderRadius:BorderRadius.circular(10.0), ), ), ); } }
- 方案2:如果需要保留
Function?的泛用性,在赋值时手动做适配
将onTap的赋值逻辑改为包裹无参匿名函数的写法:
onTap: () => onPress?.call(),
该写法会在点击时安全调用onPress,即使后续onPress调整为带参数/有返回值的类型,也能兼容运行不会报错。
内容的提问来源于stack exchange,提问作者Taha Kerrouzi
相关产品推荐
相关产品推荐

