假设我创建了以下变量:
s=John
i=12345
f=3.14
所有这些变量都以字符串形式存储在内存中,还是bash
有其他数据类型?
答案1
Bash 变量是无类型的。
与许多其他编程语言不同,Bash 不按“类型”分隔其变量。本质上,Bash 变量是字符串,但是根据上下文,Bash 允许对变量进行算术运算和比较。决定因素是变量的值是否仅包含数字。
作为另一个答案说,有一种弱形式用 打字declare
。
这是某些编程语言中可用的类型 [1] 的一种非常弱的形式。
看一个例子:
declare -i number # The script will treat subsequent occurrences of "number" as an integer. number=3 echo "Number = $number" # Number = 3 number=three echo "Number = $number" # Number = 0 # Tries to evaluate the string "three" as an integer.
参考:
答案2
Bash 本质上有普通标量变量、数组和关联数组。此外,标量可以用以下标记为整数declare
内置。从脚本程序员/shell 用户的角度来看,字符串变量充当字符串,整型变量充当整数,而数组则根据其类型。内部实现不是很相关。
但是,如果我们想知道数据实际上是如何存储在内存中的,我们必须检查源代码以了解程序实际上做了什么。
在 Bash 4.4 中,标量存储为字符串,无论整数标记如何。这可以在struct variable
/ SHELL_VAR
typedef的定义并在功能make_variable_value
,它将整数显式转换为字符串以进行存储。
数组存储在看起来像链表的地方(array.h
),以及作为哈希表的关联数组。其中的值再次存储为字符串。数组链表的选择可能看起来很奇怪,但由于数组可以是稀疏的,并且索引可以是任意数字,无论数组包含的元素有多少,这种设计选择更容易理解。
然而,该代码还包含一个定义没用过union _value
,包含整数、浮点数以及字符串值的字段。它在评论中被标记为“面向未来”,因此 Bash 的某些未来版本可能会以其本机形式存储不同类型的标量。
答案3
在我的一生中,我找不到用如此多的语言来表达这一点,但这就是我的理解。
Bash 是一个解释器,而不是编译器,并将所有变量表示为字符串。因此,所有的努力和重点都伴随着各种扩展。
Bash 通行证全部命名变量declare
作为字符串属性控制该变量的方式扩大通过declare
存储。
banana=yellow #no call to declare
declare -p banana
declare -- banana="yellow" #but declare was invoked with --
declare -i test=a #arithmetic expansion to null/zero
declare -p test
declare -i test="0"
declare -i test2=5+4 #successful arithmetic expansion
declare -p test2
declare -i test2="9"
declare -i float=99.6 #arithmetical expansion fails due to syntax
bash: declare: 99.6: syntax error: invalid arithmetic operator (error token is ".6")
nofloat=99.9
declare -p nofloat
declare -- nofloat"99.6" #Success because arithmetical expansion not invoked
declare -a a #variable is marked as a placeholder to receive an array
declare -p a
declare -a a
a[3]=99 #array elements are appended
a[4]=99
declare -p a
declare -a a=([3]="99" [4]="99")
declare -A newmap #same as -a but names instead of numbers
newmap[name]="A Bloke"
newmap[designation]=CFO
newmap[company]="My Company"
declare -p newmap
declare -A newmap=([company]="My Company" [name]="A Bloke" [designation]="CFO" )
而且当然
declare -ia finale[1]=9+16
declare -p finale
declare -ai finale=([1]="25")
结尾是,即使declare
内部表示随属性标志而变化,bash 看到或想要看到的都是字符串。
答案4
这是无关紧要的。
与 Bash 变量交互的唯一方法是通过 Bash,所以它是不可能的让您注意到变量如何存储在内存中的任何差异,因为您可以永远不要直接通过内存访问它们,你总是需要向 Bash 询问它们的值,然后 Bash 可以以任何它想要的方式翻译它们看就好像他们有以任何特定方式存储。
事实上,它们甚至可能没有存储在内存中根本不。我不知道 Bash 的常见实现有多聪明,但至少在简单的情况下可以确定是否将使用变量和/或是否将修改它,并将其完全优化或内联。