Swift-为什么String转换Int的结果是nil
摘要
知其然,更要知其所以然。前段时间用 String 转换 Int 处理时,发现一种情况返回 nil,就换成 String 转换 Double 的方式处理。今天就要来看看这种返回 nil 的情况是怎么造成的。
当有小数的 String 文本转换为 Int 类型时,返回的值并不是咱们想要的向下取整后的整数,而是 nil。
// Int 转换为 String
let intStr = "2.78"
let int = Int(intStr) // nil
为什么是nil?今天就来解解这个疑惑。
String 转换 Int 本质
首先com+鼠标左键弹出选项,选择jump to Definition(跳转到定义)一波操作,来到 Int 的定义地方,直接全局搜索一下 String,直接看下定义。
/// Creates a new integer value from the given string.
///
/// The string passed as `description` may begin with a plus or minus sign
/// character (`+` or `-`), followed by one or more numeric digits (`0-9`).
///
/// let x = Int("123")
/// // x == 123
///
/// If `description` is in an invalid format, or if the value it denotes in
/// base 10 is not representable, the result is `nil`. For example, the
/// following conversions result in `nil`:
///
/// Int(" 100") // Includes whitespace
/// Int("21-50") // Invalid format
/// Int("ff6600") // Characters out of bounds
/// Int("10000000000000000000000000") // Out of range
///
/// - Parameter description: The ASCII representation of a number.
@inlinable public init?(_ description: String)
出处找到了,不想费力看注释的,直接看我给的结论:
String 转换为 Int 类型,传入 Int 的 description 参数,必须是一个或者多个0-9组合的整数,整数前可以加“+”或者“-”。通俗说,这个 text 文本必须是一个整数。否则都返回 nil。
看到现在,大致可以明白了Int("2.78")为什么是 nil。
String 转换 Double 本质
看完String 转换 Double 本质后,顺势也看下String 转换 Double 本质。同样的查找逻辑一波操作,找到它的定义
extension Double : LosslessStringConvertible {
/// Creates a new instance from the given string.
///
/// The string passed as `text` can represent a real number in decimal or
/// hexadecimal format or special floating-point values for infinity and NaN
/// ("not a number").
///
/// The given string may begin with a plus or minus sign character (`+` or
/// `-`). The allowed formats for each of these representations is then as
/// follows:
///
/// - A *decimal value* contains the significand, a sequence of decimal
/// digits that may include a decimal point.
///
/// let c = Double("-1.0")
/// // c == -1.0
///
/// let d = Double("28.375")
/// // d == 28.375
///
/// 此处省略 57 行注释------------------
///
/// - Parameter text: The input string to convert to a `Double` instance. If
/// `text` has invalid characters or is in an invalid format, the result
/// is `nil`.
@inlinable public init?<S>(_ text: S) where S : StringProtocol
@available(macOS 11.0, iOS 14.0, watchOS 7.0, tvOS 14.0, *)
public init?(_ text: Substring)
}
Double(string)中的 string 文本可以是一个10进制、16进制或者浮点数的数(这个非常关键)。也可以添加“+”,“-”符号。
这里简单总结一下,Double 转换为 text,并保留几位小数的处理方法,加深一些印象
let double = Double(2.7895)
// double 转换为 String
print("\(double)") // 输出 "2.7895"
// 保留两位小数
print(String(format:"%.2f", double) // 输出 "2.79"
Int("2.78") 怎么处理,不是 nil?
看完了上面两个转换的定义之后,那么是否可以组合一下,解决可能出现的 nil?那是当然。
首先将文本转换为 Double,然后将 Double 转换为 Int。
Int(Double("2.78")!) // 2
Double 转换 Int
代码验证没有问题,那么就看看,Double 转换 Int 做了什么事情。
/// Creates an integer from the given floating-point value, rounding toward
/// zero.
///
/// Any fractional part of the value passed as `source` is removed, rounding
/// the value toward zero.
///
/// let x = Int(21.5)
/// // x == 21
/// let y = Int(-21.5)
/// // y == -21
///
/// - Parameter source: A floating-point value to convert to an integer.
/// `source` must be representable in this type after rounding toward
/// zero.
public init(_ source: Double)
定义中可以看到,Double 类型的数据,经过 Int 转换后,会生成一个只保留整数的数(小数部分略去)。所以也就支持了上节部分的处理方式。
Double 类型整数省略 .000
在看 Double 转换 Int定义时,无意间发现一个好玩的定义,先上定义
/// Creates an integer from the given floating-point value, if it can be
/// represented exactly.
///
/// If the value passed as `source` is not representable exactly, the result
/// is `nil`. In the following example, the constant `x` is successfully
/// created from a value of `21.0`, while the attempt to initialize the
/// constant `y` from `21.5` fails:
///
/// let x = Int(exactly: 21.0)
/// // x == Optional(21)
/// let y = Int(exactly: 21.5)
/// // y == nil
///
/// - Parameter source: A floating-point value to convert to an integer.
public init?(exactly source: Double)
定义说明,可以将一个精确标示的浮点数转换为 Int 类型。这里的精确标示就是没有小数的值。有了这个定义,那么岂不是可以解决某一个应用场景了吗?
显示存在需要保留2位小数的文本时,当浮点数是一个没有小数的数值,那么就显示整数。
// old
String(format: "%.2f", 2.578) // 2.58
String(format: "%.2f", 2.0) // 2.00
// new
if Int(exactly: 2.00) != nil {
"\(Int(exactly: 2.00)!)" // 2
}
题外话
感谢看到这里,感觉有一点收获,给个小赞。有分析的不到位,评论区留言帮我梳理。
偶尔有一些想要搞清楚的问题,评论区告诉我,咱们一起解决。
Swift-为什么String转换Int的结果是nil的更多相关文章
- swift 中String,Int 等类型使用注意,整理中
swfit中的String和Int是 struct定义的,不同于NSString和NSNumber, 如果想在一个数组中同时包含String和Int,那么这个数组要声明为[Any] 而不是 [AnyO ...
- java 13-4 Integer和String、int之间的转换,进制转换
1.int类型和String类型的相互转换 A.int -- String 推荐用: public static String valueOf(int i) 返回 int 参数的字符串表示形式. B. ...
- (二)javascript中int和string转换
在javascript里怎么样才能把int型转换成string型 (1)var x=100 a = x.toString() (2)var x=100; a = x +""; // ...
- C# 中怎么将string转换成int型
int intA = 0;1.intA =int.Parse(str);2.int.TryParse(str, out intA);3.intA = Convert.ToInt32(str);以上都可 ...
- C++有没有string转化int的函数,怎样转换
有两种方法1. c++中string到int的转换 1) 在C标准库里面,使用atoi: #include <cstdlib>#include <string> std::st ...
- Go语言string,int,int64 ,float转换
(1)int转string s := strconv.Itoa(i)等价于s := strconv.FormatInt(int64(i), 10) (2)int64转string i := int64 ...
- go语言学习--string、int、int64互相转换,字符串的截取,数组和字符串的转换
下面总结了go中常用的转换 #string到int int,err:=strconv.Atoi(string) #string到int64 int64, err := strconv.ParseInt ...
- golang学习笔记13 Golang 类型转换整理 go语言string、int、int64、float64、complex 互相转换
golang学习笔记13 Golang 类型转换整理 go语言string.int.int64.float64.complex 互相转换 #string到intint,err:=strconv.Ato ...
- Android-Kotlin-函数表达式&String与Int转换$异常处理
Kotlin的函数表达式: package cn.kotlin.kotlin_base03 /** * 函数第一种写法 */ fun addMethod1(number1: Int, number2: ...
随机推荐
- 使用Relay部署编译ONNX模型
使用Relay部署编译ONNX模型 本文介绍如何使用Relay部署ONNX模型的入门. 首先,必须安装ONNX软件包. 一个快速的解决方案是安装protobuf编译器,然后 pip install o ...
- 循环IRNNv2Layer实现
循环IRNNv2Layer实现 IRNNv2Layer实现循环层,例如循环神经网络(RNN),门控循环单元(GRU)和长期短期记忆(LSTM).支持的类型为RNN,GRU和LSTM.它执行循环操作,该 ...
- ARM Cortex-M嵌入式C基础编程(下)
ARM Cortex-M嵌入式C基础编程(下) ARM Cortex-M Embedded C Fundamentals/Tutorial -Aviral Mittal Load Region Vs ...
- 24GHz和77GHz毫米波雷达技术细节
24GHz和77GHz毫米波雷达技术细节 FMCW Radar Sensitivity Measurement Tech Field Test and Raw Data Analysis Capabi ...
- 算法训练 区间k大数查询(题解)
资源限制 时间限制:1.0s 内存限制:256.0MB 问题描述 给定一个序列,每次询问序列中第l个数到第r个数中第K大的数是哪个. 输入格式 第一行包含一个数n,表示序列长度. 第二行包 ...
- JavaScript 中精度问题以及解决方案
JavaScript 中的数字按照 IEEE 754 的标准,使用 64 位双精度浮点型来表示.其中符号位 S,指数位 E,尾数位M分别占了 1,11,52 位,并且在 ES5 规范 中指出了指数位E ...
- 保存数据到csv文件报错:Permission denied: './train_data.csv'
如果你此前已经输出,创建了文件,很有可能是你打开了此文件,导致写入不进去报错,关掉文件重新运行程序即可!
- 【Java】Debug断点调试常用技巧
Debug操作技巧 Show Execution Point 将光标回到当前断点停顿的地方 Step Over 执行当前行代码,并将运行进度跳转到下一行. Step Into 进入到当前代码行的方法内 ...
- Git操作文档
Git 操作文档 Git 是一个十分流行的版本控制系统,Git 和 SVN 区别在于,SVN使用增量文件系统,存储每次提交之间的差异.而 git 使用全量文件系统,存储每次提交的文件的全部内容(sna ...
- mybatis-generator的使用心得
之前开发了一个亚健康测评系统,使用的是SSM框架,里面第一次使用到了mybatis-generator逆向代码生成工具,很方便,省去了基本的增删改查的mapper文件及sql的编写,还能避免错误,这里 ...