flutter - 如何正确检查来自 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) {
}
解决方案
好吧,让我们创建几个方法来检查我们是否可以从字符串中获取双精度,或者它不能在一个要调用的方法中处理所有内容
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 ...
}
奇迹般有效
推荐阅读
- php - Foreach 循环只处理一个元素
- python - 按月查找每个组中最早的记录
- python - 打开文本文件时出现“OSError:[Errno 36] 文件名太长”
- apache - 带有问号的 URL 重定向
- javascript - 如何用javascript给某个td一个类名?
- javascript - 具有相同状态名称的多个组件,在父div上单击时更改一个而不影响其他人?
- hbase - 带空格的 Hbase 行键
- python - BigTable - 删除/跳过前 N 行
- powershell - 通过 Powershell 获取具有特定域的 Office 365 用户
- unity3d - 跳跃时重力不影响玩家