数据类型 / 编程语言 / 转换 · 2023年 10月 9日 0

类型转换

97 次浏览

编程语言中必然有很多情况需要转换类型。比如引入const的概念就为了提高安全性,编译器提前检查,避免一些意外修改。当然,有时,我们希望手动转换一个变量的类型,让其变成常量,可以利用编译器提供的cast方法。

  • C++早期提供了const_cast,写法繁琐,C++17引入std::as_const写法更轻松,C++20引入bit_cast可实现位级别复制,而非普通float和int转换后丢失小数位的问题。

隐式转换和强制转换

编译器为了简化不同类型变量互操作,引入隐式转换,可以安全转换(不损失数据)数据,此过程由编译器自动完成。当不满足如上条件,需要程序员手动用强制类型转换。

  • C/ObjC/C++ 语言大小小于int的整型(包括char和枚举)的类型使用时都自动转换成int. 有人有疑问,这样不是占用空间变大吗?事实上,仅仅是使用时,数据保存依然按对应类型。为什么使用时要转换成int呢?因为CPU操作int最自然,换成char或short一样会使用int大小的寄存器,没好处。下图push eax保存字符c,并传递给printf做参数。
  • Swift 是一门相对安全的语言,没有隐式类型转换。

父类子类转换

子类本身就是父类的一种,转换成父类很自然,但父类转换成子类就需要考虑对不对。

  • C++提供dynamic_cast主要为了继承体系转换,比static_cast更智能。虽然C++支持强制转换,必要时也可以通过typeid判断类型是否一致。
  • Java默认也不允许父到子转换,但如果确定父对象引用确实是子对象,可用强制类型转换。
  • C#不提供基类强转成派生类的方法。
  • Python提供了简单的转换方式type(<Derived Class>)(<Base Class>).
  • JS ES6虽然引入了类,一般无必要做父类子类转换。
  • Go/Rust并不是纯粹的OOP语言,需要做一些手脚。

枚举

  • C/C++常规枚举可以和整形做隐式转换,C++11引入作用域为类的枚举,不允许此行为以加强安全性,但可以使用显式转换。

浮点数和整数的转换

  • C/ObjC/C++/仓颉
    浮点数转换成整数,会丢弃小数。