Java 如何处理Python~静态类型?
我来自Java世界,我想知道除了在编译代码时遗漏错误之外,Python中的动态类型还有什么了不起的地方Java 如何处理Python~静态类型?,java,python,static-typing,dynamic-typing,Java,Python,Static Typing,Dynamic Typing,我来自Java世界,我想知道除了在编译代码时遗漏错误之外,Python中的动态类型还有什么了不起的地方 你喜欢Python的类型吗?你有没有一个例子说明它在一个大项目中起到了作用?这不是很容易出错吗?这是你的心头负担。您可以将红色视为“红色”(一个常量)或“255,0,0”(一个元组)或“#FF0000”(一个字符串):三种不同的格式,需要三种不同的类型,或者Java中复杂的查找和转换方法 它使代码更简单 例如,您可以编写函数 可以将整数作为 以及字符串、列表或 字典或其他任何东西,而且 将能够
你喜欢Python的类型吗?你有没有一个例子说明它在一个大项目中起到了作用?这不是很容易出错吗?这是你的心头负担。您可以将红色视为“红色”(一个常量)或“255,0,0”(一个元组)或“#FF0000”(一个字符串):三种不同的格式,需要三种不同的类型,或者Java中复杂的查找和转换方法 它使代码更简单 例如,您可以编写函数 可以将整数作为 以及字符串、列表或 字典或其他任何东西,而且 将能够透明地处理 以适当的方式(或 如果无法处理,则引发异常 类型)。你可以这样做 也用其他语言,但通常 你必须求助于(ab)使用东西 比如指针、引用或 typecasts,为用户打开孔 编程错误,它只是 非常难看
由于您来自Java世界,显而易见的答案是,不要被迫编写所有您被迫编写的内容,而只是为了让Java的类型系统满意,这是很好的 当然,还有其他静态类型检查语言不会强迫您编写Java强迫您编写的所有内容 甚至C#也对局部方法变量进行类型推断 还有其他静态类型检查语言提供了比Java更多的编译时错误检查 (不太明显的答案是——Python中的动态类型有什么好处?——可能需要更多地理解Python才能理解。) 你喜欢Python语言吗 它是Python的一部分。在Python中喜欢它是愚蠢的 你有没有一个例子说明它在一个大项目中起到了作用 对。每一天,我都为自己能够做出改变而感到高兴——因为Duck类型——它们被合理地本地化了,通过了所有的单元测试,通过了所有的集成测试,并且没有任何东西在其他地方被破坏 如果这是Java,那么这些更改将需要无休止的重构来从类中提取接口,这样我就可以引入Java静态类型检查仍然允许的变体 这不是有点容易出错吗 不比静态类型更重要。一个简单的单元测试确认对象符合预期的特征
用Java编写一个类很容易,(a)通过编译时检查,(b)在运行时严重崩溃。石膏是一种很好的方法。未能满足类的意图是一件常见的事情——类可以编译,但仍然不能工作。在一般情况下,静态类型检查是不可判定的。这意味着有些程序是静态类型安全的,但类型检查器无法证明它们是静态类型安全的,因此类型检查器必须拒绝这些程序 换句话说,类型检查器不允许您编写类型安全程序。或者,更简洁地说:静态类型阻止您编写某些程序 这通常适用于所有静态类型,而不仅仅是Java 特别是Java:它有一个相当糟糕的类型系统。它的类型系统没有足够的表达能力来表达甚至非常简单的属性。例如:在
static void java.util.Arrays.sort(Object[]a)
的类型中,它实际上是说结果必须被排序吗?或者数组元素必须是部分有序的
Java的另一个问题是,它的类型系统有很大的漏洞,您可以驾驶卡车通过:
String[] a = new String[1];
Object[] b = a;
b[0] = 1; // ArrayStoreException
这个特殊情况下的问题是协变数组。数组不可能同时具有协变性和类型安全性
Java结合了静态类型的所有麻烦,但没有任何优势。所以,你最好摆脱这些麻烦
但是,请注意,这并不是通用的。还有其他一些语言有更好的类型系统,但它们之间的取舍却不那么明确
例如,Python中有史以来最愚蠢的语言基准(斐波那契):
def fib(n):
if n < 2: return n
return fib(n-2) + fib(n-1)
或者这个:
fibs = 0 : 1 : zipWith (+) fibs (tail fibs)
实际上,Java和Python之间更重要的区别不是Java是静态类型的,Python是动态类型的,而是Java不是一种好的编程语言,而Python是。所以,Java总是会失败,不是因为它是静态类型的,而是因为它是垃圾。与BASIC和Haskell相比,Haskell显然获胜,但再次强调,不是因为它是静态类型的,而是因为BASIC是垃圾
一个更有趣的比较是Java与BASIC或Python与Haskell。我怀疑绝大多数非平凡Java程序中都有动态类型 在Java中,每次从对象转换为显式类型时,都要进行动态类型检查——这包括在1.5中引入泛型之前对集合类的每次使用。实际上,Java泛型仍然可以将某些类型检查推迟到运行时 每次使用Java反射时,您都在进行动态类型检查。这包括从文本文件中的类或方法名称映射到真实的类或方法,例如每次使用SpringXML配置文件时 这会使Java程序变得脆弱和容易出错吗?Java程序员是否花费大量时间来跟踪和修复错误的动态类型问题?可能不会——Python程序员也不会 动态键入的一些优点:
- 大大减少了对继承的依赖。我见过有大量继承树的Java程序。Python程序通常很少使用或不使用继承,更喜欢使用duck类型李>
- 编写真正的泛型代码很容易。F
def fib(n: int) -> int: if n < 2: return n return fib(n-2) + fib(n-1)
fib n | n < 2 = n | otherwise = fib (n-2) + fib (n-1)
fib 0 = 0 fib 1 = 1 fib n = fib (n-2) + fib (n-1)
fibs = 0 : 1 : zipWith (+) fibs (tail fibs)