除了“强制转换”之外,还有其他方法可以在 Java 和 C++ 等静态类型语言中更改变量类型吗?
我试图弄清楚动态类型和静态类型在实际方面的主要区别是什么,并不断寻找非常学术的定义。我想知道就我的代码的外观而言这意味着什么。
除了“强制转换”之外,还有其他方法可以在 Java 和 C++ 等静态类型语言中更改变量类型吗?
我试图弄清楚动态类型和静态类型在实际方面的主要区别是什么,并不断寻找非常学术的定义。我想知道就我的代码的外观而言这意味着什么。
确保您不会将静态类型与动态类型与强类型与弱类型相混淆。
这两个对立面可以自由组合:
通常,静态类型意味着编译器会捕获很多错误,这些错误是动态类型语言中的运行时错误——但这也意味着您花费大量时间担心类型,在许多情况下是不必要的(参见接口与鸭子打字)。
强类型意味着类型之间的任何转换都必须是显式的,要么通过强制转换,要么通过使用转换方法(例如,将字符串解析为整数)。这意味着更多的键入工作,但具有让您控制事物的优势,而当系统执行一些模糊的隐式转换时,弱类型通常会导致混乱,这会给您留下一个完全错误的变量值,从而导致严重破坏十个方法调用线。
在 C++/Java 中,您不能更改变量的类型。
静态类型:变量在编译类型时分配了一种类型并且不会改变。
动态类型:变量的类型可以在运行时改变,例如在 JavaScript 中:
js> x="5" <-- String
5
js> x=x*5 <-- Int
25
主要区别在于,在动态类型语言中,直到您在运行时使用方法时才知道该方法是否存在。在静态类型语言中,检查是在编译时进行的,如果方法不存在,则编译失败。
我想知道就我的代码的外观而言这意味着什么。
类型系统不一定对代码的外观有任何影响,例如,具有静态类型、类型推断和隐式转换的语言(例如 Scala)看起来很像动态类型语言。另请参阅:辩论类型系统之前要了解的内容。
您不需要显式转换。在许多情况下,隐式转换有效。
例如:
int i = 42;
float f = i; // f ~= 42.0
int b = f; // i == 42
class Base {
};
class Subclass : public Base {
};
Subclass *subclass = new Subclass();
Base *base = subclass; // Legal
Subclass *s = dynamic_cast<Subclass *>(base); // == subclass. Performs type checking. If base isn't a Subclass, NULL is returned instead. (This is type-safe explicit casting.)
但是,您不能更改变量的类型。不过,您可以在 C++ 中使用联合来实现某种动态类型。
让我们看看 Java 的静态类型语言和 JavaScript 的动态。在 Java 中,对于对象,变量是对对象的引用。对象具有运行时类型,引用具有类型。引用的类型必须是运行时对象的类型或其祖先之一。这就是多态性的工作原理。您必须强制转换以向上引用类型的层次结构,但不能向下。编译器确保满足这些条件。在像 JavaScript 这样的语言中,你的变量就是一个变量。你可以让它指向你想要的任何对象,并且在你检查之前你不知道它的类型。
但是,对于转换,有很多方法,如 Java 中的 toInteger 和 toFloat 来进行转换并生成具有相同相对值的新类型的对象。在 JavaScript 中也有转换方法,但它们也会生成新对象。
无论您是否使用静态类型语言,您的代码实际上应该看起来并没有太大的不同。仅仅因为您可以在动态类型语言中更改变量的数据类型,并不意味着这样做是个好主意。
例如,在 VBScript 中,匈牙利符号通常用于指定变量的首选数据类型。这样你就可以很容易地发现代码是否混合了类型。(这不是匈牙利符号的原始用法,但它非常有用。)
通过保持相同的数据类型,您可以避免难以判断代码实际做什么的情况,以及代码根本无法正常工作的情况。例如:
Dim id
id = Request.QueryString("id") ' this variable is now a string
If id = "42" Then
id = 142 ' sometimes turned into a number
End If
If id > 100 Then ' will not work properly for strings
使用匈牙利符号,您可以发现混合类型的代码,例如:
lngId = Request.QueryString("id") ' putting a string in a numeric variable
strId = 42 ' putting a number in a string variable