首页 > 解决方案 > 如何正确检查来自 JSON 的输入数据是否为双倍?

问题描述

试图找到一种在运行时检查的正确方法,如果输入数据是双倍的。让我们以此代码为例:


List<dynamic> data = [
  {"lat": 47.480088391416935, "lng": -16.237792798261637},
  , 
];

double calc( double lat2, double long2 ){
  double lat1 = 48.68370745897208;
  double long1 = -27.048339622524924;
  double p = 0.017453292519943295;
  double distance = 0.0
  double res = 0.0;
    try {
      res = 0.5 -
          cos((lat2 - lat1) * p) / 2 +
          cos(lat1 * p) * cos(lat2 * p) * (1 - cos((long2 - long1) * p)) / 2;
      return distance = 12742 * asin(sqrt(res));
    } catch (e) {
      print('Error: $e');
      return 0.0;
    }
  }

当我像这样指定函数参数时:

double calc(double lat2, double long2) {
}

然后我在calc使用错误类型参数调用函数时得到保护:例如,字符串:

print(calc(47.480088391416935,"-16.237792798261637"));

但是 calc() 内部的运行时类型检查,它验证 lat 和 long 是双精度的,但不起作用:

if (value is! double)或者if (value.runtimeType != double)


List<dynamic> data = [
  {"lat": 47.480088391416935, "lng": -16.237792798261637},
  , 
];

double calc( double lat2, double long2 ){
  double lat1 = 48.68370745897208;
  double long1 = -27.048339622524924;
  // input validation #1
  if (lat2 is! double || long2 is! double){
    return 0.0;
  }
  // input validation #2
  if (value.runtimeType != double || value.runtimeType != double){
    return 0.0;
  }
  double p = 0.017453292519943295;
  double distance = 0.0
  double res = 0.0;
    try {
      res = 0.5 -
          cos((lat2 - lat1) * p) / 2 +
          cos(lat1 * p) * cos(lat2 * p) * (1 - cos((long2 - long1) * p)) / 2;
      return distance = 12742 * asin(sqrt(res));
    } catch (e) {
      print('Error: $e');
      return 0.0;
    }
  }

当我使用时,(#1 和#2)都返回 false: double calc( double lat2, double long2 )

当我使用动态类型时:

double calc(lat2, lon2){
}

运行时类型检查有效,但调用函数时没有检查calc(lat2, lon2)

// no warning in this case
print(calc(47.480088391416935,"-16.237792798261637"));

所以,问题是 - 同时进行检查的最佳解决方案是:在调用函数时对参数进行类型检查,在运行时在函数内部进行类型检查。

try catch而且,顺便说一句,当我们有这样的cos((lat2 - lat1)错误输入 时,为什么会保持沉默:print(calc(47.480088391416935,"-16.237792798261637"));

UPD 我想将有关类型的所有异常处理移至 calc() 函数,因此在调用 calc() 的所有地方都不需要这样做:

try {
   print(calc(47.480088391416935,-16.237792798261637));
} catch (e) {
}

标签: flutterdart

解决方案


好吧,让我们创建几个方法来检查我们是否可以从字符串中获取双精度,或者它不能在一个要调用的方法中处理所有内容

class DoubleFromStringTest {

  /// lets just make a method that takes dynamic and returns double
  /// and it should process the strings and doubles
  static double getDoubleIfPossible(dynamic input){
    double _output;

    print('starting : getDoubleIfPossible : input : ${input}');
    print('starting : getDoubleIfPossible : input.runtimeType : ${input.runtimeType}');

    /// some safety layer first
    if (input != null){

      /// when its already a double,, we are good
      if (input.runtimeType == double){

        _output = input;
      }

      /// when its a string
      else if (input.runtimeType == String){

        /// we need to make sure that it's a double inside a string,, and not a combination of doubles & characters in one string like '15X8wS'
        /// so lets do an another method and call it here
        bool _inputIsDoubleInsideAString = _objectIsDoubleInString(input);

        if (_inputIsDoubleInsideAString == true){

          /// so its a double inside a string,, then we can get the double now without firing an error
          _output = _stringToDouble(input);

        }

        // else {
        //   /// input is not a double in a string
        //   /// will do nothing,, and the _output shall return null
        //   /// so I will comment these unnecessary lines
        // }


      }

      // /// it not a string and its not a double
      // else {
      //   /// do nothing and return null
      //   /// so I will comment these unnecessary lines
      // }

    }

    return _output;
  }

  static bool _objectIsDoubleInString(dynamic string) {

    bool _objectIsDoubleInString;
    double _double;

    if (string != null){
      _double = double.tryParse(string.trim());
    }

    if (_double == null){
      _objectIsDoubleInString = false;
    } else {
      _objectIsDoubleInString = true;
    }

    print('objectIsDoubleInString : _double is : $_double');

    return _objectIsDoubleInString;

  }

  static double _stringToDouble(String string){
    double _value;

    if (string != null){
      _value = double.parse(string);
    }

    return _value;
  }

}

然后让我们做一个方法测试,看看这是否有效

 test("testing double from a string", () async {

    String _inputA = '34.55';
    double _output = DoubleFromStringTest.getDoubleIfPossible(_inputA);
    expect(_output, 34.55);

    String _inputB = 'XX34.55';
    double _outputB = DoubleFromStringTest.getDoubleIfPossible(_inputB);
    expect(_outputB, null);

    String _inputC = 'XAfdjdb4';
    double _outputC = DoubleFromStringTest.getDoubleIfPossible(_inputC);
    expect(_outputC, null);

    String _inputD = '178712364871624.83762874623';
    double _outputD = DoubleFromStringTest.getDoubleIfPossible(_inputD);
    expect(_outputD, 178712364871624.83762874623);

  });

然后在 calc(double a, double b) 之前使用此方法

把它放在里面

calc(dynamic a, dynami b){
  final double _a = DoubleFromStringTest.getDoubleIfPossible(a);
  final double _b = DoubleFromStringTest.getDoubleIfPossible(b);

// do things ...
    }

奇迹般有效


推荐阅读