简体   繁体   English

如何使用 Dart 中的 compute() 方法为 function 传递多个命名参数?

[英]How to pass multiple named parameters for a function using the compute() method in Dart?

How would one go about using the compute() method with a top-level function that only accepts multiple named parameters?一个 go 如何将 compute() 方法与仅接受多个命名参数的顶级 function 一起使用?

I tried using function helpers to do the named parameter conversion but I get an Exception:我尝试使用 function 助手进行命名参数转换,但出现异常:

Exception has occurred.发生异常。 ArgumentError (Invalid argument(s): Illegal argument in isolate message: (object is a closure - Function 'helper':.)) ArgumentError(无效参数:隔离消息中的非法参数:(对象是一个闭包 - Function 'helper':.))

How should I go about this?我应该如何 go 关于这个?

Here's some sample code for a Flutter widget.这是 Flutter 小部件的一些示例代码。

import 'dart:convert';
import 'dart:math';

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

class Sampler extends StatefulWidget {
  @override
  _SamplerState createState() => _SamplerState();
}

class _SamplerState extends State<Sampler> {
  String result = 'No Samples Yet!';

  @override
  Widget build(BuildContext context) {
    return Container(
      child: Column(
        children: <Widget>[
          Text(result),
          RaisedButton(
            child: Text('Sample!'),
            onPressed: _generateSample,
          )
        ],
      ),
    );
  }

  Future<void> _generateSample() async {
    Map<Symbol, dynamic> symbolizeKeys(Map<String, dynamic> map) {
      final result = new Map<Symbol, dynamic>();
      map.forEach((String k, v) {
        result[new Symbol(k)] = v;
      });
      return result;
    }

    Map<String, int> helper(Map<String, Object> params) {
      final paramsConverted = symbolizeKeys(params);

      return Function.apply(sampleDistribution, [], paramsConverted);
    }

    var _samples = await compute(helper, {
      'strings': ['a', 'b'],
      'probaDistribution': [0.4, 0.6],
      'numSamples': 10000
    });
    setState(() {
      result = json.encode(_samples);
    });
  }
}

Map<String, int> sampleDistribution(
    {List<String> strings, List<double> probaDistribution, int numSamples}) {
  // assert(strings.length == probaDistribution.length);
  // assert(probaDistribution.reduce((a, b) => a + b) == 1.0);

  List<double> cdf = [];
  List<double> probas = generateUniformProbas(numSamples: numSamples);
  Map<String, int> result =
      Map.fromIterable(strings, key: (s) => s, value: (s) => 0);

  double tmp = 0;
  for (double i in probaDistribution) {
    tmp += i;
    cdf.add(tmp);
  }

  for (double proba in probas) {
    var stringIndex = cdf.indexWhere((p) => p > proba);
    var selectedString = strings[stringIndex];

    result[selectedString] = result[selectedString] + 1;
  }

  return result;
}

List<double> generateUniformProbas({int numSamples = 1}) {
  var randomGenerator = new Random();
  List<double> result = [];
  for (int i = 0; i < numSamples; i++) {
    result.add(randomGenerator.nextDouble());
  }

  return result;
}

Oops, the compute function only accepts top-level functions.糟糕,计算 function 只接受顶级函数。 Just moving that out gets a working result.只需将其移出即可获得工作结果。

import 'dart:convert';
import 'dart:math';

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

class Sampler extends StatefulWidget {
  @override
  _SamplerState createState() => _SamplerState();
}

class _SamplerState extends State<Sampler> {
  String result = 'No Samples Yet!';

  @override
  Widget build(BuildContext context) {
    return Container(
      child: Column(
        children: <Widget>[
          Text(result),
          RaisedButton(
            child: Text('Sample!'),
            onPressed: _generateSample,
          )
        ],
      ),
    );
  }

  Future<void> _generateSample() async {
    var _samples = await compute(helper, {
      'strings': ['a', 'b'],
      'probaDistribution': [0.4, 0.6],
      'numSamples': 100000
    });
    setState(() {
      result = json.encode(_samples);
    });
  }
}

Map<Symbol, dynamic> symbolizeKeys(Map<String, dynamic> map) {
  final result = new Map<Symbol, dynamic>();
  map.forEach((String k, v) {
    result[new Symbol(k)] = v;
  });
  return result;
}

Map<String, int> helper(Map<String, Object> params) {
  final paramsConverted = symbolizeKeys(params);

  return Function.apply(sampleDistribution, [], paramsConverted);
}

Map<String, int> sampleDistribution(
    {List<String> strings, List<double> probaDistribution, int numSamples}) {
  // assert(strings.length == probaDistribution.length);
  // assert(probaDistribution.reduce((a, b) => a + b) == 1.0);

  List<double> cdf = [];
  List<double> probas = generateUniformProbas(numSamples: numSamples);
  Map<String, int> result =
      Map.fromIterable(strings, key: (s) => s, value: (s) => 0);

  double tmp = 0;
  for (double i in probaDistribution) {
    tmp += i;
    cdf.add(tmp);
  }

  for (double proba in probas) {
    var stringIndex = cdf.indexWhere((p) => p > proba);
    var selectedString = strings[stringIndex];

    result[selectedString] = result[selectedString] + 1;
  }

  return result;
}

List<double> generateUniformProbas({int numSamples = 1}) {
  var randomGenerator = new Random();
  List<double> result = [];
  for (int i = 0; i < numSamples; i++) {
    result.add(randomGenerator.nextDouble());
  }

  return result;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM