谁告诉的你们Python是强类型语言!站出来,保准不打你
<div style="color: black; text-align: left; margin-bottom: 10px;"><img src="https://p3-sign.toutiaoimg.com/pgc-image/cb3f7a7e10824258bba554deaa950f31~noop.image?_iz=58558&from=article.pc_detail&lk3s=953192f4&x-expires=1723891585&x-signature=pkjeEvG5tm95R2NnKGlhrnpkj08%3D" style="width: 50%; margin-bottom: 20px;"></div>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> <strong style="color: blue;">1. 真的能用隐式类型转换<span style="color: black;">做为</span>强弱类型的判断标准吗?</strong></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">近期</span>有些学员问我,Python到底是强类型语言,还是弱类型语言。我就直接脱口而出:Python是弱类型语言。没想到有<span style="color: black;">有些</span>学员给我了<span style="color: black;">有些</span><span style="color: black;">文案</span>,有中文的,有英文的,都说Python是强类型语言。其它中文的<span style="color: black;">关联</span><span style="color: black;">文案</span>,<span style="color: black;">大众</span><span style="color: black;">能够</span>去网上搜,一堆,<span style="color: black;">这儿</span>就不一一列举了。</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">我先不说这些结论对不对,我先总结一下这些<span style="color: black;">文案</span>的核心观点。这些<span style="color: black;">文案</span>将编程语言分为强类型、弱类型、动态类型和静态类型。这4个概念的解释如下:</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">强类型:<span style="color: black;">倘若</span>一门语言不对变量的类型做隐式转换,这种编程语言就被<span style="color: black;">叫作</span>为强类型语言 ;</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">弱类型:与强类型相反,<span style="color: black;">倘若</span>一门语言对变量的类型做隐式转换,那<span style="color: black;">咱们</span>则<span style="color: black;">叫作</span>之为弱类型语言;</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">动态类型:<span style="color: black;">倘若</span>一门语言<span style="color: black;">能够</span>在运行时改变变量的类型,那<span style="color: black;">咱们</span><span style="color: black;">叫作</span>之为动态类型语言;</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">静态类型:与动态类型相反,<span style="color: black;">倘若</span>一门语言不<span style="color: black;">能够</span>在运行时改变变量的类型,则<span style="color: black;">叫作</span>之为静态类型语言;</p>
<div style="color: black; text-align: left; margin-bottom: 10px;"><img src="https://p3-sign.toutiaoimg.com/pgc-image/6b65e47450ba4ca5a470484ce4de13e6~noop.image?_iz=58558&from=article.pc_detail&lk3s=953192f4&x-expires=1723891585&x-signature=rFuyUdNeqLIPVCuHdMNV56Owl7s%3D" style="width: 50%; margin-bottom: 20px;"></div>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> 其实这些概念就<span style="color: black;">触及</span>到编程语言的两个特性:隐式类型转换和类型固化。</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">所说</span>类型固化,<span style="color: black;">便是</span>指一旦变量在初始化时被确定了某个数据类型(如整数类型),<span style="color: black;">那样</span>这个变量的数据类型将永远不会变化。</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">关于动态类型和静态类型,在本文的后面再来讨论,<span style="color: black;">这儿</span>先探讨强类型和弱类型。</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">此刻</span>姑且认为这个结论没问题。强类型<span style="color: black;">便是</span>不<span style="color: black;">准许</span>做隐式类型转换。OK,<span style="color: black;">咱们</span><span style="color: black;">瞧瞧</span>用这个隐式类型转换来判断强类型和弱类型<span style="color: black;">是不是</span><span style="color: black;">恰当</span>。</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">在这些<span style="color: black;">文案</span>中,给出了<span style="color: black;">非常多</span>例子<span style="color: black;">做为</span>证据来证实这个结论,其中最典型的例子是在Python语言中,int + string是不合法的,没错,确实不合法。如执行1 + abc会抛出<span style="color: black;">反常</span>。当然,还有人给出了另一个例子:string / int<span style="color: black;">亦</span>是不合法的,如执行666 / 20会抛出<span style="color: black;">反常</span>,没错,字符串与整数的确<span style="color: black;">不可</span>直接相除。那你怎么<span style="color: black;">不消</span>乘号举例呢?如abc * 10,这在Python中可是合法的哦,<span style="color: black;">由于</span>这个表达式会将abc复制10份。<span style="color: black;">为么</span><span style="color: black;">不消</span>我大乘号来举例,难道瞧不起我大乘号吗? 这是运算符<span style="color: black;">卑视</span>?</p>
<div style="color: black; text-align: left; margin-bottom: 10px;"><img src="https://p3-sign.toutiaoimg.com/pgc-image/e495f3777b034d07b5df4e2d3136d21d~noop.image?_iz=58558&from=article.pc_detail&lk3s=953192f4&x-expires=1723891585&x-signature=g6mYVcnczJyvFHfBNG6IKTnnnDI%3D" style="width: 50%; margin-bottom: 20px;"></div>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">PS:虽然abc * 10<span style="color: black;">无</span>做类型转换,但<span style="color: black;">这儿</span>说的是乘号(*),尽管<span style="color: black;">日前</span>Python不支持abc * 10的操作,但已有<span style="color: black;">亦</span>有可能会支持abc * 10,<span style="color: black;">亦</span><span style="color: black;">便是</span>将10转换为10,这就<span style="color: black;">出现</span>了类型转换。</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">另一</span>,难道没听说过Python支持运算符重载吗?<span style="color: black;">经过</span>运算符重载,<span style="color: black;">能够</span>让两个类型完全<span style="color: black;">区别</span>的变量或值在<span style="color: black;">一块</span>运算,如相加,看下面的例子:</p><span style="color: black;"><span style="color: black;">class</span> <span style="color: black;">MyClass1</span>:</span>
<span style="color: black;"><span style="color: black;">def</span> <span style="color: black;">__init__</span><span style="color: black;">(<span style="color: black;">self</span>,value)</span></span>:
<span style="color: black;">self</span>.value = value
<span style="color: black;"><span style="color: black;">class</span> <span style="color: black;">MyClass2</span>:</span>
<span style="color: black;"><span style="color: black;">def</span> <span style="color: black;">__init__</span><span style="color: black;">(<span style="color: black;">self</span>,value)</span></span>:
<span style="color: black;">self</span>.value = value
my1 = MyClass1(<span style="color: black;">20</span>)
my2 = MyClass2(<span style="color: black;">30</span>)
print( my1 + my2)<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">倘若</span>执行这段代码,100%会抛出<span style="color: black;">反常</span>,<span style="color: black;">由于</span>MyClass1和MyClass2肯定<span style="color: black;">不可</span>相加,但<span style="color: black;">倘若</span>按下面的方式修改代码,就没问题了。</p><span style="color: black;"><span style="color: black;">class</span> <span style="color: black;">MyClass1</span>:</span>
<span style="color: black;"><span style="color: black;">def</span> <span style="color: black;">__init__</span><span style="color: black;">(<span style="color: black;">self</span>,value)</span></span>:
<span style="color: black;">self</span>.value = value
<span style="color: black;"><span style="color: black;">def</span> <span style="color: black;">__add__</span><span style="color: black;">(<span style="color: black;">self</span>,my)</span></span>:
<span style="color: black;">return</span> <span style="color: black;">self</span>.value + my.value
<span style="color: black;"><span style="color: black;">class</span> <span style="color: black;">MyClass2</span>:</span>
<span style="color: black;"><span style="color: black;">def</span> <span style="color: black;">__init__</span><span style="color: black;">(<span style="color: black;">self</span>,value)</span></span>:
<span style="color: black;">self</span>.value = value
<span style="color: black;"><span style="color: black;">def</span> <span style="color: black;">__add__</span><span style="color: black;">(<span style="color: black;">self</span>,my)</span></span>:
<span style="color: black;">return</span> <span style="color: black;">self</span>.value + my.value
my1 = MyClass1(<span style="color: black;">20</span>)
my2 = MyClass2(<span style="color: black;">30</span>)
print( my1 + my2)<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> 这段代码对MyClass1和MyClass2进行了加法运算符重载,<span style="color: black;">这般</span>两个<span style="color: black;">区别</span>类型的变量就<span style="color: black;">能够</span>直接相加了,从表面上看,<span style="color: black;">好似</span>是<span style="color: black;">出现</span>了类型转换,但其实是运算符重载。</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">当然,运算符重载<span style="color: black;">亦</span>可能会<span style="color: black;">运用</span>显式类型转换,如下面的代码<span style="color: black;">准许</span><span style="color: black;">区别</span>类型的值相加。</p><span style="color: black;"><span style="color: black;">class</span> <span style="color: black;">MyClass1</span>:</span>
<span style="color: black;"><span style="color: black;">def</span> <span style="color: black;">__init__</span><span style="color: black;">(<span style="color: black;">self</span>,value)</span></span>:
<span style="color: black;">self</span>.value = value
<span style="color: black;"><span style="color: black;">def</span> <span style="color: black;">__add__</span><span style="color: black;">(<span style="color: black;">self</span>,my)</span></span>:
<span style="color: black;">return</span> str(<span style="color: black;">self</span>.value) + str(my.value)
<span style="color: black;"><span style="color: black;">class</span> <span style="color: black;">MyClass2</span>:</span>
<span style="color: black;"><span style="color: black;">def</span> <span style="color: black;">__init__</span><span style="color: black;">(<span style="color: black;">self</span>,value)</span></span>:
<span style="color: black;">self</span>.value = value
<span style="color: black;"><span style="color: black;">def</span> <span style="color: black;">__add__</span><span style="color: black;">(<span style="color: black;">self</span>,my)</span></span>:
<span style="color: black;">return</span> str(<span style="color: black;">self</span>.value) + str(my.value)
my1 = MyClass1(<span style="color: black;">20</span>)
my2 = MyClass2(<span style="color: black;">"xyz"</span>)
print( my1 + my2)<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">其实这段代码<span style="color: black;">亦</span>就相当于int + string形式了,只是用MyClass1和MyClass2包装了一层。可能有<span style="color: black;">非常多</span><span style="color: black;">朋友</span>会说,这能<span style="color: black;">同样</span>吗?<span style="color: black;">显著</span>不是int + string的形式,ok,的确是不太<span style="color: black;">同样</span>。</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">可惜<span style="color: black;">日前</span>Python还不支持内建类型(如int、str)的运算符重载,但<span style="color: black;">不可</span><span style="color: black;">保准</span>以后不支持,<span style="color: black;">倘若</span>以后Python要是支持内建类型运算符重载,那就<span style="color: black;">寓意</span>着<span style="color: black;">能够</span>重载str类的__add__<span style="color: black;">办法</span>了,<span style="color: black;">日前</span>str类定义在builtins.py文件中,里面<span style="color: black;">已然</span>预定义了<span style="color: black;">非常多</span>可能被重载的运算符。当然,<span style="color: black;">日前</span>Python是直接将这些运算符<span style="color: black;">办法</span>固化在解析器中了,例如,__add__<span style="color: black;">办法</span>是只读的,<span style="color: black;">不可</span>修改。如下面的Python代码相当于a + "ok"。</p>a = <span style="color: black;">"abc"</span>
<span style="color: black;">print</span>( a.__add__(<span style="color: black;">"ok"</span>))<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">但你<span style="color: black;">不可</span>用下面的代码覆盖掉str类的__add__<span style="color: black;">办法</span>。</p><span style="color: black;"><span style="color: black;">def</span> <span style="color: black;">new_add</span><span style="color: black;">(<span style="color: black;">self</span>, value)</span></span>:
<span style="color: black;">return</span> str(<span style="color: black;">self</span>) + str(value)
str.__add_<span style="color: black;">_</span> = new_add <span style="color: black;"># 抛出<span style="color: black;">反常</span></span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">执行这段代码会抛出如下图的<span style="color: black;">反常</span>,<span style="color: black;">亦</span><span style="color: black;">便是</span>说,<span style="color: black;">日前</span>Python的内建类型,如str,是<span style="color: black;">不可</span>动态为其添加新的成员或覆盖以前的成员的。</p>
<div style="color: black; text-align: left; margin-bottom: 10px;"><img src="https://p3-sign.toutiaoimg.com/pgc-image/0027e93454004925a4ed2dbb8b270806~noop.image?_iz=58558&from=article.pc_detail&lk3s=953192f4&x-expires=1723891585&x-signature=6Lc4n6c8lCSS%2B2HDZRT%2BbDw6YTs%3D" style="width: 50%; margin-bottom: 20px;"></div>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">但<span style="color: black;">此刻</span><span style="color: black;">不可</span>,不<span style="color: black;">表率</span>以后<span style="color: black;">不可</span>。<span style="color: black;">倘若</span>以后Python支持覆盖内建类型的运算符,<span style="color: black;">那样</span>int + string就<span style="color: black;">能够</span>让其合法化。<span style="color: black;">不外</span>可能还会有<span style="color: black;">朋友</span>问,就算内建类型支持运算符重载,那不还<span style="color: black;">必须</span><span style="color: black;">运用</span>显式类型转换吗?是的,没错,<span style="color: black;">必须</span>类型转换。</p>
<div style="color: black; text-align: left; margin-bottom: 10px;"><img src="https://p3-sign.toutiaoimg.com/pgc-image/947cde4436d54334ac279374f0f1c059~noop.image?_iz=58558&from=article.pc_detail&lk3s=953192f4&x-expires=1723891585&x-signature=vuL3UcK8jT01u2jqLXRYSQGnMTY%3D" style="width: 50%; margin-bottom: 20px;"></div>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> <span style="color: black;">此刻</span><span style="color: black;">咱们</span>先来谈谈类型转换,先用<span style="color: black;">另一</span>一个被公认的弱类型编程语言JavaScript为例。在JS中,1 + abc是合法的、444/20<span style="color: black;">亦</span>是合法的,<span style="color: black;">因此</span>就有<span style="color: black;">非常多</span>人认为js是弱类型语言,没错,js的确是弱类型语言。但弱类型确实是<span style="color: black;">按照</span>1 + abc和444/20得出来的?</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">有<span style="color: black;">非常多</span>人认为,JavaScript不做类型<span style="color: black;">检测</span>,就直接将1和abc相加了!你是当真的?<span style="color: black;">倘若</span>不做类型<span style="color: black;">检测</span>,<span style="color: black;">那样</span>js怎么会<span style="color: black;">晓得</span><span style="color: black;">怎样</span>将1和abc相加,为啥不将1当做1.0呢?<span style="color: black;">并不</span>管是什么类型的编程语言,数据类型检测都是<span style="color: black;">必要</span>的,不管是js、还是Python,或是Java,内部<span style="color: black;">必定</span>会做数据类型检测,只是检测的目的<span style="color: black;">区别</span><span style="color: black;">罢了</span>。在Python中,进行数据类型检测后,<span style="color: black;">发掘</span>不合规的<span style="color: black;">状况</span>,有时会自动处理(如int+float),有时干脆就抛出<span style="color: black;">反常</span>(如int + string)。而在Java中就更严格了,在编译时,<span style="color: black;">发掘</span>不合规的<span style="color: black;">状况</span>,就直接抛出编译错误了。在js中,<span style="color: black;">发掘</span>不合规的<span style="color: black;">状况</span>,就会按最大可能进行处理,在内部进行类型转换。对,不是不管数据类型了,而是在内部做的数据类型转换。<span style="color: black;">那样</span>这和<span style="color: black;">经过</span>Python的运算符重载在<span style="color: black;">外边</span>做类型转换有什么区别呢?只是一个由编译器(解析器)内部处理的,一个是在<span style="color: black;">外边</span>由程序员编写代码处理的!<span style="color: black;">况且</span>就算Python不会支持内建类型的运算符重载,<span style="color: black;">那样</span><span style="color: black;">亦</span>有可能直接支持int + string的形式。<span style="color: black;">由于</span><span style="color: black;">日前</span>Python不支持,<span style="color: black;">因此</span>正确的Python代码不可能有int + string的形式。<span style="color: black;">因此</span><span style="color: black;">倘若</span>以后支持int + string的形式,<span style="color: black;">亦</span><span style="color: black;">能够</span>完全做到代码向下兼容。就算Python<span style="color: black;">将来</span>不支持int + string形式,<span style="color: black;">那样</span>我自己做一个Python解析器(例如,<span style="color: black;">咱们</span>团队<span style="color: black;">此刻</span>自己做的Ori语言,支持类型隐式转换,<span style="color: black;">不外</span><span style="color: black;">实质</span>上是生<span style="color: black;">成为了</span>其他的编程语言,<span style="color: black;">亦</span><span style="color: black;">便是</span>语言之间的转换,这是不是<span style="color: black;">表率</span>Ori是弱类型语言呢?),完全兼容Python的代码,只<span style="color: black;">不外</span>支持int+string形式,<span style="color: black;">那样</span>能<span style="color: black;">不可</span>说,我的这个Python版本是弱类型Python呢?这很正常,<span style="color: black;">由于</span>像C++这种语言<span style="color: black;">亦</span>有<span style="color: black;">非常多</span>种实现版本,Python<span style="color: black;">一样</span><span style="color: black;">亦</span><span style="color: black;">能够</span><span style="color: black;">持有</span>,只<span style="color: black;">不外</span><span style="color: black;">日前</span>没多少人做<span style="color: black;">罢了</span>,但不等于<span style="color: black;">无</span>可能。</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">倘若</span>Python真这么做了,<span style="color: black;">那样</span>能<span style="color: black;">不可</span>说Python又从强类型语言变<span style="color: black;">成为了</span>弱类型语言呢?<span style="color: black;">倘若</span><span style="color: black;">大众</span>认为一种语言的类型强弱是<span style="color: black;">能够</span>随着时间变化的,<span style="color: black;">那样</span>我无话可说!</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">总之,<span style="color: black;">必须</span>用一种确定不会变的特性来<span style="color: black;">暗示</span>强弱类型才是最合适的。<span style="color: black;">一般</span>来讲,某种语言的变量一旦数据类型确定了,就不<span style="color: black;">准许</span>变化了,这种才<span style="color: black;">能够</span><span style="color: black;">叫作</span>为强类型,强大到类型一言九鼎,类型一旦确定,就不<span style="color: black;">准许</span>变了,而Python显然不是,x = 20; x = abc;<span style="color: black;">一样</span>是合法的,x先后分别是int和str类型。</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">PS:<span style="color: black;">这儿</span>再给<span style="color: black;">大众</span>一个表,<span style="color: black;">一般</span>编程语言中确定类型<span style="color: black;">是不是</span>兼容,<span style="color: black;">便是</span><span style="color: black;">经过</span>类似的表处理的。这个表<span style="color: black;">重点</span>用于内建类型,<span style="color: black;">倘若</span>是自定义类型,<span style="color: black;">必须</span><span style="color: black;">经过</span>接口(实现)和类(继承)类确定类型<span style="color: black;">是不是</span>兼容。</p>
<div style="color: black; text-align: left; margin-bottom: 10px;"><img src="https://p3-sign.toutiaoimg.com/pgc-image/e63fa443a0fc4f459f04fd8b83c4f570~noop.image?_iz=58558&from=article.pc_detail&lk3s=953192f4&x-expires=1723891585&x-signature=00aAtv9AT%2BLoNmxOw%2BqMlVUq%2F5Y%3D" style="width: 50%; margin-bottom: 20px;"></div>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">这个表只给出了3个数据类型:int、float和str。<span style="color: black;">按照</span>业务<span style="color: black;">区别</span>,这个表<span style="color: black;">能够</span>有多种用途,例如,赋值,<span style="color: black;">是不是</span><span style="color: black;">能够</span>进行运算等。<span style="color: black;">这儿</span>就只<span style="color: black;">思虑</span>进行加法运算。 其中True<span style="color: black;">暗示</span><span style="color: black;">准许</span>进行加法运算,False<span style="color: black;">暗示</span>不<span style="color: black;">准许</span>进行加法运算,很显然,<span style="color: black;">倘若</span>是int + int形式,第1个操作数<span style="color: black;">能够</span>从第1列<span style="color: black;">查询</span>,第2个操作数<span style="color: black;">能够</span>从第1行<span style="color: black;">查询</span>,找到了(1,1)的位置,该位置是True,<span style="color: black;">因此</span>int + int是合法的,int + float,float + float、str + str的情形类似,<span style="color: black;">倘若</span>遇到int + str,就会找到(1,3)或(3,1),这两个位置都是False,就<span style="color: black;">显示</span>int + str是不合法的。其实Python和JavaScript都进行到了这一步。只<span style="color: black;">不外</span>Python就直接抛出了<span style="color: black;">反常</span>,而JS则尝试进行类型转换,但都<span style="color: black;">必须</span>进行类型检测。<span style="color: black;">由于</span>类型转换<span style="color: black;">必须</span>确定数据类型的优先级,优先级低的会转换为优先级高的类型,如str的优先级比int高,<span style="color: black;">因此</span>int会转换为str类型。float比int高,<span style="color: black;">因此</span>int会转换为float类型,这就<span style="color: black;">触及</span>到<span style="color: black;">另一</span>一个类型优先级表了。</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">按照</span>这个表可知,编程语言只是在遇到类型不合规的<span style="color: black;">状况</span>下处理的方式<span style="color: black;">区别</span>,这<span style="color: black;">便是</span>编译器(解析器)的业务<span style="color: black;">规律</span>了,这个业务<span style="color: black;">规律</span>随时可能变(<span style="color: black;">一般</span>不会影响程序的向下兼容),<span style="color: black;">因此</span>是<span style="color: black;">不可</span>用这一特性<span style="color: black;">做为</span>强弱语言标识的,否则强类型和弱类型语言就有可能会<span style="color: black;">持续</span>切换了,<span style="color: black;">由于</span>编程语言会<span style="color: black;">持续</span>进化的。</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><strong style="color: blue;">2. <span style="color: black;">为何</span>应该用类型固化<span style="color: black;">做为</span>强弱类型的标识</strong></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">那样</span><span style="color: black;">为何</span><span style="color: black;">能够</span>用类型固化<span style="color: black;">做为</span>强弱类型的标识呢?<span style="color: black;">由于</span>类型固化<span style="color: black;">一般</span>是不可变的,<span style="color: black;">那样</span><span style="color: black;">为何</span>是不可变的呢?下面用Python来举例:</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">下面的Python代码是合法的。x从int变<span style="color: black;">成为了</span>str,类型并<span style="color: black;">无</span>固化,所有Python是弱类型语言。</p><span style="color: black;">x</span> = <span style="color: black;">20</span>
<span style="color: black;">x</span> = <span style="color: black;">abc</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">那样</span>有<span style="color: black;">无</span>可能Python以后对类型进行固化呢?从技术上<span style="color: black;">来讲</span>,完全没问题,但从代码兼容性问题上,将会<span style="color: black;">导致</span>严重的后果。<span style="color: black;">由于</span>类型没固化属于宽松型,一旦类型固化,属于严格型。以前<span style="color: black;">已然</span>遗留了<span style="color: black;">非常多</span>宽松的代码,一旦严格,<span style="color: black;">那样</span>就<span style="color: black;">寓意</span>着x = abc将会抛出<span style="color: black;">反常</span>,就会<span style="color: black;">导致</span><span style="color: black;">非常多</span>程序<span style="color: black;">没法</span>正常运行。<span style="color: black;">因此</span><span style="color: black;">倘若</span>Python这么做,就相当于一种新语言了,如PythonX,而<span style="color: black;">不可</span>再<span style="color: black;">叫作</span>为Python了。就像人类进化,无论从远古的尼安德特人,还是智人,或是现代各个国家的人,无论怎么进化,都<span style="color: black;">必须</span>在主线上发展,例如,都有一个脑袋,两条腿,两个胳膊。当然,可能细节不同,如黑眼睛,黄头发等。你<span style="color: black;">不可</span>进化出两个头,8条腿来,当然<span style="color: black;">能够</span>这么进化,但这个就<span style="color: black;">不可</span>再<span style="color: black;">叫作</span>为人了,<span style="color: black;">便是</span><span style="color: black;">另一</span>一种生物了。</p>
<div style="color: black; text-align: left; margin-bottom: 10px;"><img src="https://p3-sign.toutiaoimg.com/pgc-image/9a26431d8f8d430fbf656bd7f820edab~noop.image?_iz=58558&from=article.pc_detail&lk3s=953192f4&x-expires=1723891585&x-signature=zf5U6O9U%2BL1e5dByLzEPwLHkHvo%3D" style="width: 50%; margin-bottom: 20px;"></div>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> <span style="color: black;">此刻</span>再看一个相反的例子,<span style="color: black;">倘若</span>一种编程语言(如Java)是强类型的,能否以后变成弱类型语言呢?</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">看下面的Java代码:</p><span style="color: black;">int</span> x = <span style="color: black;">20</span>;
x = <span style="color: black;">"200"</span>; <span style="color: black;">// 出错</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">其实从技术上和兼容性上这么做是没问题的。但<span style="color: black;">亦</span>会有<span style="color: black;">非常多</span>其他问题,如编译器(或运行时)的处理方式完全<span style="color: black;">区别</span>,<span style="color: black;">咱们</span><span style="color: black;">晓得</span>,类型固化的程序要比类型不固化的程序运行效率高,<span style="color: black;">由于</span>类型不固化,<span style="color: black;">必须</span><span style="color: black;">持续</span>去<span style="color: black;">思虑</span>类型转换的问题。<span style="color: black;">况且</span>在空间分配上更麻烦,有可能会<span style="color: black;">持续</span>分配新的内存空间。例如,<span style="color: black;">针对</span>一个数组<span style="color: black;">来讲</span>,js和python(<span style="color: black;">便是</span>列表)是<span style="color: black;">能够</span>动态扩容的,其实这个方式效率很低,<span style="color: black;">必须</span>用算法在<span style="color: black;">恰当</span>的范围内<span style="color: black;">持续</span>分配新的内存空间,而Java<span style="color: black;">区别</span>,数组一旦分配内存空间,是不可变的,<span style="color: black;">亦</span><span style="color: black;">便是</span>空间固化(类似于类型固化),<span style="color: black;">这般</span>的运行效率非常高。</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">因此</span>一旦编程语言从类型固化变成类型不固化,尽管<span style="color: black;">能够</span><span style="color: black;">保准</span>代码的兼容性,但编译器或运行时的内部实现机理将完全改变,<span style="color: black;">因此</span>从本质上说,<span style="color: black;">亦</span>是<span style="color: black;">另一</span>一种编程语言了。就像人类的进化,尽管从表面上符合人类的所有特征。但内部<span style="color: black;">已然</span>变成生化人了,<span style="color: black;">已然</span>不是血肉之躯了,这<span style="color: black;">亦</span><span style="color: black;">不可</span><span style="color: black;">叫作</span>为人类了。</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">因此</span>无论往哪个方向变化,都会形成<span style="color: black;">另一</span>一种全新的编程语言,<span style="color: black;">因此</span>用类型固化来<span style="color: black;">做为</span>强弱类型标识是完全<span style="color: black;">无</span>问题的。</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><strong style="color: blue;">3. C++、Java、Kotlin是强类型语言,还是弱类型语言</strong></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">我看到网上有<span style="color: black;">非常多</span><span style="color: black;">文案</span>将C++归为弱类型语言。其实,这我是头一次听说C++有人认为是弱类型语言,是<span style="color: black;">由于</span>C++支持string+int的写法吗?没错,C++是支持这种写法,但直接这么写,语法没问题,但不会得到<span style="color: black;">咱们</span>期望的结果,如下面的代码:</p><span style="color: black;">std</span>::<span style="color: black;">cout</span> << <span style="color: black;">"Hello, World!"</span> + <span style="color: black;">3</span> << <span style="color: black;">std</span>::<span style="color: black;">endl</span>; <p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">这行代码并不会输出Hello,World!3,<span style="color: black;">想要</span>输出正常的结果,<span style="color: black;">必须</span>进行显式类型转换,代码如下:</p><span style="color: black;">std</span>::<span style="color: black;">cout</span> << <span style="color: black;">"Hello, World!"</span> + <span style="color: black;">std</span>::to_string(<span style="color: black;">3</span>) << <span style="color: black;">std</span>::<span style="color: black;">endl</span>;<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">尽管C++编译器支持string+int的写法,但得不到<span style="color: black;">咱们</span>期望的结果,<span style="color: black;">因此</span>C++的string和int相加<span style="color: black;">必须</span>进行转换。<span style="color: black;">因此呢</span>,仅仅<span style="color: black;">经过</span>string+int或类似的<span style="color: black;">区别</span>类型<span style="color: black;">不可</span>直接在<span style="color: black;">一块</span>运算来判断语言<span style="color: black;">是不是</span>是强类型和弱类型的规则是站不住脚的。<span style="color: black;">况且</span>C++<span style="color: black;">亦</span>支持运算符重载,<span style="color: black;">亦</span>就<span style="color: black;">寓意</span>着<span style="color: black;">能够</span>让"abc" + 4变成不合法的。</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">那样</span>Java是强类型还是弱类型呢?Java是强类型语言,<span style="color: black;">由于</span><span style="color: black;">非常多</span><span style="color: black;">文案</span>给出了下面的例子(或类似):</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">"666" / 4;</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">是的,这个表达式会出错,但你不要忘了,Java支持下面的表达式:</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">"666" + 4;</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">这行表达式输出了6664,为啥<span style="color: black;">不消</span>加号(+)举例呢?前面<span style="color: black;">卑视</span>Python的乘号,<span style="color: black;">此刻</span>又<span style="color: black;">卑视</span>Java里的加号吗?其实这是<span style="color: black;">由于</span>前面描述的类型优先级问题,<span style="color: black;">因为</span>string的优先级高于int,<span style="color: black;">因此呢</span>4会转换为"4"。<span style="color: black;">因此</span>"666" / 4其实会<span style="color: black;">亦</span>会<span style="color: black;">出现</span>隐式类型转换,变成"666"/"4",两个字符串自然<span style="color: black;">不可</span>相除了,而"666" + 4会变成"666" + "4",两个字符串当然<span style="color: black;">能够</span>相加了。这<span style="color: black;">便是</span>个语义的问题,和强弱类型有毛关系。</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">因此</span>吗?Java是强类型语言没错,但判断依据错了。</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">Kotlin是强类型还是弱类型呢?答案是Kotlin是强类型语言。<span style="color: black;">不外</span>Kotlin支持运算符重载,看下面的代码。</p><span style="color: black;"><span style="color: black;">class</span> <span style="color: black;">MyClass</span></span>(<span style="color: black;">var</span> value: <span style="color: black;">Int</span>) {
<span style="color: black;">operator</span> <span style="color: black;"><span style="color: black;">fun</span> <span style="color: black;">plus</span><span style="color: black;">(other: <span style="color: black;">Int</span>)</span></span>: <span style="color: black;">Int</span> {
<span style="color: black;">return</span>value + other;
}
}<span style="color: black;"><span style="color: black;">fun</span> <span style="color: black;">main</span><span style="color: black;">()</span></span> {
<span style="color: black;">var</span> my: MyClass = MyClass(<span style="color: black;">200</span>);
print(my + <span style="color: black;">20</span>); <span style="color: black;">// 输出220</span>
}<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">咱们</span>都<span style="color: black;">晓得</span>,Kotlin<span style="color: black;">亦</span>是JVM上的一种编程语言(尽管<span style="color: black;">能够</span>生成js,但<span style="color: black;">必须</span>用Kotlin专有API),而Java是不支持运算符重载的,在同一个运行时(JVM)上,有的语言支持运算符重载,有的语言不支持运算符重载。从这一点就<span style="color: black;">能够</span>看出,运算符来处理两侧的操作数,只<span style="color: black;">不外</span>是个语法糖<span style="color: black;">罢了</span>。想让他支持什么样的运算都<span style="color: black;">能够</span>,如,"abcd" / "cd",其实<span style="color: black;">亦</span><span style="color: black;">能够</span>让它合法化,例如,语义就<span style="color: black;">暗示</span>去掉分子以分母为后缀的子字符串,<span style="color: black;">倘若</span><span style="color: black;">无</span>该后缀,分子保持不变,<span style="color: black;">因此</span>,"abcd"/"cd"的结果<span style="color: black;">便是</span>"ab",而"abcd"/"xy"的结果还是"abcd",语法糖<span style="color: black;">罢了</span>,与强弱类型<span style="color: black;">无</span>半毛钱关系。</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><strong style="color: blue;">4. 静态语言和动态语言</strong></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">此刻</span><span style="color: black;">来讲</span>说静态语言和动态语言。 有人说<span style="color: black;">能够</span>用<span style="color: black;">是不是</span>实时(在运行时)改变变量类型判别是静态语言还是动态语言,没错,变量类型的实时改变确实是动态语言的特征之一,但并不是<span style="color: black;">所有</span>。动态语言的另<span style="color: black;">有些</span>特征是<span style="color: black;">能够</span>随时随地为类【或其他类似的语法元素】(<span style="color: black;">重点</span><span style="color: black;">指的是</span>自定义的类,有<span style="color: black;">有些</span>语言可能不支持对内建类型和系统类进行扩展)添加成员(<span style="color: black;">包含</span><span style="color: black;">办法</span>、属性等)。</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">例如,下面的JavaScript代码动态为MyClass类添加了一个静态<span style="color: black;">办法</span>(method1)和一个成员<span style="color: black;">办法</span>(method2)。</p><span style="color: black;"><span style="color: black;">class</span> <span style="color: black;">MyClass</span> </span>{
}
<span style="color: black;">// 动态添加静态<span style="color: black;">办法</span></span>
MyClass.method1 = <span style="color: black;"><span style="color: black;">function</span> () </span>{
<span style="color: black;">console</span>.log(<span style="color: black;">static method</span>);
}
MyClass.method1()
<span style="color: black;">var</span> my = <span style="color: black;">new</span> MyClass();
<span style="color: black;">// 动态添加成员<span style="color: black;">办法</span></span>
my.method2 = <span style="color: black;"><span style="color: black;">function</span> () </span>{
<span style="color: black;">console</span>.log(<span style="color: black;">common method</span>)
}
my.method2()<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">Python动态添加成员的方式与JavaScript类似,代码如下:</p><span style="color: black;"><span style="color: black;">class</span> <span style="color: black;">MyClass</span>:</span>
<span style="color: black;">pass</span>
<span style="color: black;"><span style="color: black;">def</span> <span style="color: black;">method1</span><span style="color: black;">()</span>:</span>print(<span style="color: black;">static method</span>)
<span style="color: black;"># 动态添加静态<span style="color: black;">办法</span></span>
MyClass.method1 = method1
MyClass.method1()
my = MyClass()
<span style="color: black;"><span style="color: black;">def</span> <span style="color: black;">method2</span><span style="color: black;">()</span>:</span>
print(<span style="color: black;">common method</span>)
<span style="color: black;"># 动态添加静态<span style="color: black;">办法</span></span>my.method2 = method2
my.method2()<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">还有<span style="color: black;">便是</span>数组的动态扩容(<span style="color: black;">按照</span><span style="color: black;">必定</span>的算法,并不是每一次调用push<span style="color: black;">办法</span>都会<span style="color: black;">增多</span>内存空间),如JavaScript的代码:</p><span style="color: black;">a</span> =<span style="color: black;"> []</span>
<span style="color: black;">a</span>.push(<span style="color: black;">"hello"</span>)
<span style="color: black;">a</span>.push(20)
<span style="color: black;">a</span>.push(<span style="color: black;">"world"</span>)
<span style="color: black;">console</span>.log(a)<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">Python的数组(列表)扩容:</p>a = []
a.<span style="color: black;">append</span>(<span style="color: black;">world</span>)
a.<span style="color: black;">append</span>(<span style="color: black;">20</span>)
a.<span style="color: black;">append</span>(<span style="color: black;">"hello"</span>)
<span style="color: black;">print</span>(a)<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">当然,动态语言还有<span style="color: black;">非常多</span>特性,<span style="color: black;">这儿</span>就不一一介绍了。</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">这些特性在静态语言(如Java、C++)中是<span style="color: black;">没法</span>做到的。在静态语言中,一个类一旦定义完,就<span style="color: black;">不可</span>再为类动态添加任何成员和移除任何成员,除非修改类的源代码。</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">因此</span>说,静态和动态其实涵盖了多个方面,如类型固化,动态扩展、数组扩容等。而强类型和弱类型的特性其实只能算静态和动态的特性之一。<span style="color: black;">亦</span><span style="color: black;">便是</span>说,说一种语言是静态语言,其实<span style="color: black;">已然</span><span style="color: black;">包括</span>了这种语言的变量类型一旦确定不可改变的事实,<span style="color: black;">亦</span><span style="color: black;">便是</span>静态语言<span style="color: black;">必定</span>是强类型的编程语言。</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">倘若</span>单独强调强类型,其实就相当于下面这句话:</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">这个人是一个男人,<span style="color: black;">况且</span>是一个男演员。</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">这句话看起来没毛病,<span style="color: black;">亦</span>能看懂,但其实是有语病的。<span style="color: black;">由于</span>前面<span style="color: black;">已然</span>说了这个人是一个男人了,后面就<span style="color: black;">不必</span>强调是男演员了,而只<span style="color: black;">必须</span>按下面说的<span style="color: black;">就可</span>:</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">这个人是一个男人,<span style="color: black;">况且</span>是一个演员。</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">此刻</span>来总结一下:</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">应该用固定不变的特性来标识一种语言的特性。而语言<span style="color: black;">是不是</span>支持隐式类型转换,这只是编译器或运行时的内部业务<span style="color: black;">规律</span>,相当于语法糖<span style="color: black;">罢了</span>,是随时<span style="color: black;">能够</span>改变的。而类型固化,动态扩展、数组扩容,这些<span style="color: black;">触及</span>到编程语言的<span style="color: black;">基本</span>,一旦改变,就变<span style="color: black;">成为了</span><span style="color: black;">另一</span>一种语言了,<span style="color: black;">因此</span><span style="color: black;">一般</span>用这些特性标识语言的特性。<span style="color: black;">一般</span>来讲,静态语言的效率会高于动态语言。<span style="color: black;">由于</span>,这些动态特性会让程序有更大<span style="color: black;">包袱</span>,如类型不固定,就<span style="color: black;">寓意</span>着可能会为新的类型分配新的内存空间,动态扩展和数组扩容<span style="color: black;">亦</span><span style="color: black;">寓意</span>着<span style="color: black;">持续</span>进行边界检测和分配新的内存空间(或回收旧的内存空间)。这<span style="color: black;">便是</span><span style="color: black;">为何</span>C++、Java、C#等编程语言的性能要高于js、Python的<span style="color: black;">重点</span><span style="color: black;">原由</span>。</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">其实过度强调静态、动态、强类型、弱类型,<span style="color: black;">道理</span>并不大。因为编程语言以后的发展方向是静态语言动态化,弱类型强类型化。都是互相渗透了,<span style="color: black;">倘若</span>以后<span style="color: black;">显现</span>一种编程语言,<span style="color: black;">同期</span><span style="color: black;">持有</span>静态和动态的特性,其实并不稀奇。例如,尽管变量类型不<span style="color: black;">准许</span>改变,但<span style="color: black;">准许</span>动态为对象添加成员。就和光<span style="color: black;">同样</span>,既是光子(粒子),又是电磁波,<span style="color: black;">亦</span><span style="color: black;">便是</span>说光<span style="color: black;">持有</span>波粒二象性! 编程语言<span style="color: black;">亦</span><span style="color: black;">同样</span>,<span style="color: black;">亦</span>会<span style="color: black;">同期</span><span style="color: black;">持有</span>静动态二象性!</p>
<div style="color: black; text-align: left; margin-bottom: 10px;"><img src="https://p3-sign.toutiaoimg.com/pgc-image/3f33d3cff2ed41fbbf295cc5d613d225~noop.image?_iz=58558&from=article.pc_detail&lk3s=953192f4&x-expires=1723891585&x-signature=U%2BV0AJ9DoIaoO4bF9ZtUL0xBXTo%3D" style="width: 50%; margin-bottom: 20px;"></div>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">最后,<span style="color: black;">博主</span>想说:我是一名python<span style="color: black;">研发</span>工程师,整理了一套最新的python系统学习教程,想要这些资料的<span style="color: black;">能够</span>关注私信<span style="color: black;">博主</span>“01”<span style="color: black;">就可</span>(免费分享哦)<span style="color: black;">期盼</span>能对你有所<span style="color: black;">帮忙</span>。</p>
我赞同你的看法,你的智慧让人佩服,谢谢分享。 楼主的文章非常有意义,提升了我的知识水平。 楼主果然英明!不得不赞美你一下! 百度seo优化论坛 http://www.fok120.com/ “沙发”(SF,第一个回帖的人) 我完全同意你的观点,说得太对了。 谷歌外贸网站优化技术。
页:
[1]