泡杯茶,聊聊变量

泡上一壶茶,边喝别聊,聊到哪儿算哪儿。有道是,“偷得浮生半日闲”,一话无常别梦烦。
“干杯!”
茶不错,味道刚刚好。
在编程里,需要处理数据,既然是处理数据,就要先把数据装杯子里面,然后该复制就复制,该映射就映射,要么迭代等等,便产生了两种杯具,一种是常量,一种是变量。
问题是怎么装呢?
绕不开一个目前已经成型的事情,就是编程语言有了强弱类型语言之分。为什么出现这种情况呢?懒呗,毕竟懒是人类进步的巨大动力,文明点,为了方便、快捷、高效,又因为一种语言往往包含着一种编程哲学......
故产生了弱类型语言,区别是“会隐性的进行语言类型转变”,意思就是定义了类型的变量,可以自动因地制宜地转换类型。
那么相对的强类型语言,就有了一个优点,严谨,当然,对应的缺点是麻烦。
多扯一点,动态语言是运行时检查变量类型的语言,在编写代码的时候可以不指定变量的数据类型,静态语言是编译时检查变量类型的语言,变量在使用前必须先声明类型,方便维护,也因为这个原因适合大型长期项目。我见有划分的象限图,就不挂了,没什么意义,尺有所短寸有所长,用什么语言,合适最好。
好了,喝杯茶,下面好好唠唠。

JavaScript(es6)

let a = 10;
var x=5;
const MAX = 5;

从常量开始扯,用const声明,声明同时必须赋值,为什么呢?这么说吧,const指向的是内存地址保存的数据保持不变,所以才是常量,如果可以声明而不赋值,那相当于什么呢?相当于指向了一段空的内存空间,后面的赋值就意味着这段内存空间是可更改的,这个定义其实就是变量,常量不可更改,所以声明的同时必须赋值。那有意思的来了,如果const声明的是数组和对象一类的可变复合类型的数据,这可咋整,因为数组和对象是可变的。此时

const指向的内存地址,保存的是一个指向实际数据的指针,const只能保证这个指针是固定的(即总是指向另一个固定的地址)
当然,也可以用方法进行数据冻结。

那在es6里,两种变量,一个是var,一个是let,其中,var命令和function命令声明的全局变量,是顶层对象的属性;而let命令、const命令、class命令声明的全局变量,不属于顶层对象的属性。
接下来,let和const声明的变量只在声明后的数据块内有效,这叫块作用域,(需要指出:let声明的变量如果处于循环之中,每一次的循环都是一个隔离的块作用域)在声明代码行之前同一块内,不能使用声明的变量和常量,这叫暂时性死区,名字起得真好,暂时性的嘛。既如此,var面对这种情况,会作何感想呢?var会说,去你的吧,我是全局变量,才不会跟你俩一样,只顾着自己的“一亩三分地”,啥也不管,哥们儿我“有条件要上,没有条件制造条件也要上”,虽然没有声明,但是你既然指出来这里需要个变量,那我就给你个未定义,值为undefined,但是如果直接用a=2;先赋值,那值就为2呗!为什么会这样呢?因为es6会先搜索所有的变量声明(注意:不搜索赋值,只搜索声明) ,并提前进行声明变量,这叫变量提升。而let和const也就不存在变量提升了,对应的是暂时性死区,这是一种进步,作用是为了减少运行时错误,防止在变量声明前就使用这个变量,从而导致意料之外的行为,因为在es5中,经常出现这种错误。

TypeScript

const hello : string = "Hello World!"

ts是静态检查的,设定变量要设定类型,如果未设定,能进行推断(比如var a=2;),则依此确定类型,如果不能推断,当然就是any型。
ts里当然有全局变量和局部变量(代码块内有效),都是用var声明,还有一个类作用域,变量成为字段,直接赋值(a=2;)。可以通过类的对象来访问。类变量也可以是静态的,静态的变量(static a= 10;)可以通过类名直接访问。

TypeScript 的另一个重要的特性就是坚持与 ECMAScript 标准同步发展。

所以,es6的相关内容就不扯了。

Python3

counter = 100          # 整型变量
miles   = 1000.0       # 浮点型变量
name    = "runoob"     # 字符串

直接产生变量、常量,对于变量,第二次即为调用之前变量。

Python 中的变量不需要声明。每个变量在使用前都必须赋值,变量赋值以后该变量才会被创建。

在 Python 中,变量就是变量,它没有类型,我们所说的"类型"是变量所指的内存中对象的类型。

Rust

Rust 是强类型语言,跟Python一样,但也具有自动判断变量类型的能力。

let a = 123;
let mut a = 123;     变量变得"可变"(mutable)只需一个 mut 关键字。
const a: i32 = 123;
let a: u64 = 123;    //这里声明了 a 为无符号 64 位整型变量,如果没有声明类型,a 将自动被判断为有符号 32 位整型变量,这对于 a 的取值范围有很大的影响。

重影就是指变量的名称可以被重新使用的机制。重影是指用同一个名字重新代表另一个变量实体,其类型、可变属性和值都可以变化。

这段话,是说变量名可以被重新使用,不仅仅是值得改变。但不能给字符串变量赋整型值。

计算机程序必须在运行时管理它们所使用的内存资源。

大多数的编程语言都有管理内存的功能:

C/C++ 这样的语言主要通过手动方式管理内存,开发者需要手动的申请和释放内存资源。但为了提高开发效率,只要不影响程序功能的实现,许多开发者没有及时释放内存的习惯。所以手动管理内存的方式常常造成资源浪费。

Java 语言编写的程序在虚拟机(JVM)中运行,JVM 具备自动回收内存资源的功能。但这种方式常常会降低运行时效率,所以 JVM 会尽可能少的回收资源,这样也会使程序占用较大的内存资源。

所有权对大多数开发者而言是一个新颖的概念,它是 Rust 语言为高效使用内存而设计的语法机制。所有权概念是为了让 Rust 在编译阶段更有效地分析内存资源的有用性以实现内存管理而诞生的概念。
所有权规则
所有权有以下三条规则:

Rust 中的每个值都有一个变量,称为其所有者。
一次只能有一个所有者。
当所有者不在程序运行范围时,该值将被删除。

{
    // 在声明以前,变量 s 无效
    let s = "runoob";
    // 这里是变量 s 的可用范围
}
// 变量范围已经结束,变量 s 无效

Rust 之所以没有明示释放的步骤是因为在变量范围结束的时候,Rust 编译器自动添加了调用释放资源函数的步骤。

let s1 = String::from("hello");
let s2 = s1; 

内容可能不尽如人意,欢迎探讨

你可能感兴趣的:(泡杯茶,聊聊变量)