无法将参数类型“Function”分配给参数类型“void Function()?” 空安全后

dos*_*res 35 dart flutter dart-null-safety

我想实现制作一个带有不同项目的抽屉,所以我正在为 DrawerItems 创建一个单独的文件,并使用构造函数将数据传递给主文件。但是我在“onPressed”函数上收到以下错误:

“不能将参数类型‘Function’分配给参数类型‘void Function()’”

class DrawerItem extends StatelessWidget {
    
      final String text;
      final Function onPressed;
    
      const DrawerItem({Key key, this.text, this.onPressed}) : super(key: key);
    
      @override
      Widget build(BuildContext context) {
        return FlatButton(
          child: Text(
            text,
            style: TextStyle(
              fontWeight: FontWeight.w600,
              fontSize: 18.0,
            ),
          ),
          onPressed: onPressed,
        );
      }
    }
Run Code Online (Sandbox Code Playgroud)

有谁知道为什么?

Pie*_*oon 95

更改您的代码以接受 VoidCallback 而不是 onPressed 的 Function。顺便说一句 VoidCallback 只是简写,void Function()因此您也可以将其定义为final void Function() onPressed;

更新代码:

class DrawerItem extends StatelessWidget {
    
      final String text;
      final VoidCallback onPressed;
    
      const DrawerItem({Key key, this.text, this.onPressed}) : super(key: key);
    
      @override
      Widget build(BuildContext context) {
        return FlatButton(
          child: Text(
            text,
            style: TextStyle(
              fontWeight: FontWeight.w600,
              fontSize: 18.0,
            ),
          ),
          onPressed: onPressed,
        );
      }
    }
Run Code Online (Sandbox Code Playgroud)

  • 如果我想要一个带有参数的函数,有什么解决方案吗?例如,文本字段函数“onSubscribed”,因为它给我的错误为“参数类型‘void Function()?’” 无法分配给参数类型“void Function(String)?”。此错误有解决方案吗? (2认同)
  • @HiteshDanidhariya 是的,你可以简单地将它添加到括号中,即“void Function(String myString)” (2认同)

Cop*_*oad 32

具有空安全性:

代替

final Function? onPressed;
Run Code Online (Sandbox Code Playgroud)

final Function? onPressed;
Run Code Online (Sandbox Code Playgroud)

或者

final VoidCallback? onPressed;
Run Code Online (Sandbox Code Playgroud)

  • @vietstone 一个 `Function` 可以是任何东西,比如 `Function()`、`Function(int)` 等,这就是为什么使用 Dart null 安全性,你应该明确告诉 `Function` 是什么。 (4认同)
  • 最终函数()?按下时;为我工作,谢谢:) (2认同)
  • @vietstone 多态性是另一回事。`Function onPressed` 可以通过 `onPressed()`、`onPressed(1)`、`onPressed(1, true)` 调用,因此,您可能会遇到运行时错误,但 `Function() onPressed` 只能通过 `onPressed() 调用onPressed()`。这个东西与空安全没有特别关系,而是与 Dart 2.12 有关。 (2认同)

Ham*_*mza 17

那是因为onPressedinsideFlatButton不是一个普通的函数,它的VoidCallBackFunction 。你可以尝试这样的事情:

final VoidCallBack onPressed;
Run Code Online (Sandbox Code Playgroud)

同时,您正在将法线传递functionVoidCallBack

按照此处的官方文档进行操作

在此输入图像描述

更新的代码:

import 'package:flutter/material.dart';

void main() => runApp(new MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: HomeScreen(),
    );
  }
}

class HomeScreen extends StatelessWidget {
  _myFunction() => print("Being pressed!");

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.spaceEvenly,
          children: [
            DrawerItem(
              text: "Hello Jee",
              onPressed: _myFunction,
            ),
          ],
        ),
      ),
    );
  }
}

class DrawerItem extends StatelessWidget {
  final String text;
  final Function onPressed;

  const DrawerItem({Key key, this.text, this.onPressed}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return FlatButton(
      child: Text(
        text,
        style: TextStyle(
          fontWeight: FontWeight.w600,
          fontSize: 18.0,
        ),
      ),
      onPressed: onPressed,
    );
  }
}
Run Code Online (Sandbox Code Playgroud)


小智 8

代替

final Function? onPressed; 
Run Code Online (Sandbox Code Playgroud) 使用
final Function()? onPressed; // add parenthesis in Function
Run Code Online (Sandbox Code Playgroud)


小智 7

定义函数时将括号放在关键字()后面。Function

import 'package:flutter/material.dart';

class Answer extends StatelessWidget {
  final Function() onPressed; //parenthesis () on function
  final String name;
  const Answer(this.name, this.functionMessage, {Key? key}) : super(key: 
key);

  @override
  Widget build(BuildContext context) {
    return Container(
        margin: const EdgeInsets.only(top: 10),
        width: double.infinity,
        child: ElevatedButton(
           style: ElevatedButton.styleFrom(
           primary: Colors.black, // background
           onPrimary: Colors.white, // foreground
          ),
          onPressed: onPressed,
          child: Text(name),
        ));
  }
}
Run Code Online (Sandbox Code Playgroud)


Mas*_* .H 6

如果您了解 dart 中的数据类型和 null 安全性,则有两种可能的解决方案

第一:

添加类型 VoidCallback?

class DrawerItem extends StatelessWidget {
      final String text;
      final VoidCallback? onPressed;
    
      const DrawerItem({Key key, this.text, this.onPressed}) : super(key: key); }
Run Code Online (Sandbox Code Playgroud)

第二:

如果您是初学者并且对数据类型了解不多,您可以使用动态并让 dart 编译器为您处理类型。

class DrawerItem extends StatelessWidget {
          final String text;
          final dynamic onPressed;
    
      const DrawerItem({Key key, this.text, this.onPressed}) : super(key: key); }
Run Code Online (Sandbox Code Playgroud)