二、Julia之变量与数据类型

本文介绍了Julia语言的基础知识,包括变量、数据类型等内容。详细解释了整型、浮点型、复数型等基本数据类型的特点和用法,以及字符串处理的相关技巧。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、变量

在Julia中的一个变量是一个与一个值关联(或绑定)的名称。它的作用变现在当你想存储一个值(例如,你在进行一些数学运算后得到了一些值,你需要在之后使用到这些值)时。

变量就是给数据提供一个内存标识的符号。

变量的命名规范:

  • 变量名使用小写字母
  • 单词之间使用下划线(’_’)分割,但是不鼓励使用
  • 类型名首字母大写,单词之间使用驼峰式分隔
  • 函数名和宏名使用小写字母,不使用下划线分割单词。
  • 修改参数的函数结尾使用 ! . 这样的函数被称为mutating functions 或 in-place functions

二、数据类型

使用内置函数 typemin(类型)typemax(类型) 来获得该类型能够表达的数值范围。

使用内置函数 typeof(),在任何时候查看某个值或变量等任意对象的类型。

2.1 整型

整型又分成有符号无符号两类,其中的有符号型能够表达负数而无符号型仅用于表达正数。

无符号比有符号表达的正数范围要大。

image-20201010145202336

0x表示十六进制数

0b表示二进制数

0o表示八进制数

1、类型强制限定

格式: 类型名称(输入值或变量)

示例:x2 = Int32(20) 或 x3 = Int64(a)

2、有无符号转换

有符号转为无符号:unsigned() 示例:unsigned(Int16(20))

无符号转为有符号:signed() 示例:signed(UInt32(20))

注意点:

  • unsigned()函数会忽略负值的检查
  • signed()会忽略表达范围越界(Overflow,溢出)的情况。这种情况并不会上报异常,因此在实践中需要多多留意。

2.2 布尔型

可以通过bitstring()函数查看一下true及false的内存表达方式。

查看的最终结果类似于类型Int8的1和0这两个值。

类型定义:

  • Bool(1):true

  • Bool(0):false

注意点:

在Julia中的布尔型是整型的一种,但不能将整型当布尔型使用,因为它们在设计机制和使用约束上有着许多差异,这是与其他语言不同的地方。

2.3 浮点型

image-20201010152815784

以下几种形式都是正确的:

  • 正数:1.0
  • 省略小数部分:1.
  • 省略整数部分:.5
  • 负数:-1.25
  • 科学计数法:2.5e-4

注意点:

  • 64位系统默认会选择Float64类型
  • Float16一般不使用,即使你显示的进行类型限定,参与计算时也会被处理为Float32类型

1、零的表达

浮点型在表达数值零时有些特别,存在正零和负零两种情况,因为它们的内存表达是不相同的。

Julia提供了专门的函数用于生成某类型的零值:zero()

Julia也提供了专门的函数用于生成各类型的1值:one()

2、epsilon

计算机中相邻两个浮点型值之间存在着“缝隙”,因此,会存在误差,影响着科学计算的精度。为了能够评估这种误差,相邻浮点值间这种缝隙的宽度被称为epsilon值。

使用函数**eps()**可以查看某个浮点值附近的epsilon值。

内置的nextfloat()与prefloat()函数可以分别获得某个浮点值的后继与前继浮点值。

结论:

随浮点值(绝对值)从大到小,epsilon值会呈指数级骤减,到零值处最小。epsilon值得大小关于零点对称,与浮点值的正负无关。

3、无穷值

image-20201010162211427

不论是正无穷大还是负无穷小,Julia中定义的无穷值都不是一种类型,而是浮点型的数值常量。

Julia有了对无穷值的支持,Julia中的浮点运算就可以正常地使用除零操作了。

如:julia> 1.2 / 0 = Inf

如何判断某个变量或值是否是无穷值,可通过**isfinite()isinf()**函数进行判断。

4、非数值

非数值(Not-a-Number)是Julia另外定义了一组特殊的浮点值常量。

非数值代表的是无效的浮点值,需要标记它的存在。

定义的三种浮点类型:

image-20201010163635801

可以使用函数 isnan() 来检验一个变量或数值是否为“非数值”。

5、内置常量

Julia在模块Base.MathConstants模块中定义了常见的数学或物理等方面的系数常量。

常用的内置变量如下图所示:

image-20201010164321907

使用内置变量需要导入模块Base.MathConstants

如:julia> using Base.MathConstants

这些常用变量并不是浮点类型,而是内部定义的无理数类型(Irrational)

Irrational的父类型是AbstractIrrational型。

可以使用函数typeof(pi)进行查看。

2.4 有理数型

类型名(Rational)

Rational类型是Julia中特有的,以“分子 // 分母”格式表达。其中双斜线并非是运算符,而是表达有理数结构的特定操作符。

由于对无穷值的支持,所以在Rational对象中允许分母为0,但不允许分子和分母同时为0。

image-20201010170358766

Rational类型的有理数值均可转换为浮点值:

image-20201010170916223

浮点值也能够转换到Rational数值:

image-20201010170937785

通过**numerator()denominator()**函数可以获得Rational对象的分子、分母部分。

2.5 复数型

image-20201010173234609

其中,Number是抽象类型,表示Complex是数值类型的一种;而{T<:Real}表示实部与虚部的类型T可以是Real类型的任一种,包括各种浮点型、整数型、有理数Rational型及无理数AbstractIrrational型(Irrational的父类型)等。

特别地,当T取Float16、Float32及Float64时,对应的复数型分别为Complex{Float16}、Complex{Float32}及Complex{Float64}。为了方便,Julia为它们提供了别名,即ComplexF16、ComplexF32和ComplexF64。

在创建Complex数值对象时,也可以像整型、浮点型、有理数型那样以字面值的方式提供,格式为“实部 + 虚部im”,其中的虚部标识采用了im,对应于数学中的虚部单位i.

在使用复数型表达式时,如果虚部是变量不建议使用 * 号进行书写,如下所示:

julia > a=1;b=2
julia > a + b * im
1 + 2im

推荐使用函数**complex()**进行:

julia> complex(a,b)

也可以使用复数类型声明的构造方法创建Complex类型:

julia > ComplexF32(1.0, 2.0)

针对复数的各种操作,Julia提供了各种函数:

image-20201010175756791

2.6 随机数

马特赛特旋转演算法是Julia默认采用的方法,用于制作伪随机数。

三种常见的随机数生成方法:

  • 均匀分布随机数

    函数rand()用于生成均匀分布的随机数。对于浮点类型来说,该函数生成的随机数所处的区间是[0, 1),即小于1大于等于0的浮点数。

  • 正态分布随机数

    函数randn()则是用于生成均值为0,方差为1的正态分布中的随机数。

  • 指数分布随机数

    函数randexp()用于生成符合指数分布的随机数。需要导入模块Random

image-20201010181828652

2.7 任意精度算术

在进行“超大”值进行运算时,会发生越界溢出的情况。针对此现象,Julia封装了GUN的多精度算术库和多精度浮点计算库,提供了BigIntBigFloat两个类型。

BigInt是Integer类型的一种。

BigFloat是浮点型AbstractFloat(浮点数抽象类型)的一种。

两个常用函数:

  • parse()函数:将字符串转为数值类型
  • big()函数:将不同类型的“超大”数值转为BigInt或BigFloat类型。

一种字面值的表达方式:

​ Julia特有的下划线分割方式,便于视觉上的划分。其中下划线的位置并没有明确的限制,而且与数据类型无关。

​ 10_000_000 = 10000000

image-20201010183602599

2.8 字符串

2.8.1 字符

字符是一种Char类型,是一个32位存储结构的元类型,父类型为AbstractChar抽象类型。

使用方式: ’ 单个字符’

几种使用情况:

  • 可以使用Unicode码值创建字符对象,只需要以\u 或者 \U 作为前缀输入其十六位码值即可。
  • 使用Char的构造函数创建字符对象,Char()
  • 有的Unicode码值未必有有效的字符,可以使用**isvalid()**函数进行检查
  • Julia允许将字符转换到Number类型的任意一个具体子类型,使用**convert()**函数即可。

2.8.2 String对象

字符串在Julia中是String类型,它的父类型是AbstractString。

AbstractString的字符串对象是不可变的,和java是一样的。

如何使用?

需使用成对的双引号或三组双引号表示。如:“aaa” “”“bbb”""

如果字符串中含有双引号,使用双引号时需要用反斜杠进行转义,使用三组双引号则不需要转义。

换行符的三种方式:

CR、CRLF、LF,一般分别以\r , \r\n 及 \n表示。

1、索引

在Julia中,字符串也是有索引概念的,通过索引方式取得其中任意位置的字符。

需要注意的是:Julia的索引下标是从1开始,而在java中是从0开始。

end关键字可以表示字符串索引的最后一位,而且还可以通过表达式进行计算。

同样,如果索引越界,会报越界异常BoundError。

image-20201012100046275

关于字符串中存在Unicode字符问题:

  • 由于Unicode字符是可变宽的编码方式,因此,字节数是不一样的。
  • 通过nextind(str::AbstractString, i::Integer, n::Integer=1) -> Int函数获取字符串中字符的索引值。

image-20201012100846357

prevind()函数和nextind()函数类似,前者是从后往前,相反,后者是从前往后获取下标值。

给出字符串最大索引值的两个函数:

  • lastindex()函数是按照字节移动
  • length()函数是按照字符个数

因此,两个函数获取的值是不同的。

image-20201012102016062

2、遍历

对于字符串的遍历,我们只需要知道如何解决包含Unicode字符的字符串的问题。

通过函数**length()和lastindex()**都不能遍历含有Unicode字符的字符串。

如何解决呢?

Julia提供了函数**eachindex()**函数,可以获得相应的索引值和字符。

字符串也是可迭代数集的一种,可以基于迭代器,采用元素迭代的方式进行遍历(Julia推荐)。

因为迭代器方式,可以适用于字符串的任何情况(包括含有Unicode),也是最方便、简洁的方式。

迭代器的两种语法如下

第一种:

for i in str
    ...
end

第二种:

for i ∈ str
    ...
end

image-20201012110613500

3、子串

子串指的是从一个字符串中截取出来的一个字符串。

截取的方式是根据索引范围截取。

格式:

str[初始值:边界值]

使用范围索引需要注意以下几条:

  • 范围索引使用的闭区间,故“初始值”与“边界值”对应位置的元素都会取出。
  • 如果初始值大于边界值,结果将会是空字符串。
  • 如果初始值等于边界值,取出的将是仅有一个字符的字符串,但不是字符。

2.8.3 变量替换

在Julia字符串中,美元符号 $ 是一个特殊的字符,用于表示紧随其后的是一个表达式或者变量名。

使用格式:

"$变量名"
"$(表达式)"

如果字符串中包含$,但是不代表表达式或者变量名,需要使用转义字符进行转义。

image-20201012121929797

2.8.4 正则表达式

在Julia中,正则表达式为Regex类型。

由于Regex的父类型不是AbstractString类型,它被视为一种非标准字符串。因此,对字符串的一些操作对正则表达式并不适用,包括索引、遍历、子串等。

如何定义一个正则表达式对象?

  • 在常规字符串上加入前缀 r 作为标识 如:a = r"^\s*(?:#|$)"
  • 使用构造方法Regex()从一个字符串定义一个正则表达式对象 如:Regex("^\\s*(?:#|\$)")
1、匹配

匹配指在某个字符串中查找是否存在一个或多个子串,能够符合正则表达式对象定义的字符构成模式

使用函数 occursin() 可以实现。

函数原型:occursin(r::Regex, s::AbstractString) -> Bool

示例:

occursin(r"^\s*(?:#|$)", "not a comment")
2、提取

提取是指将满足正则模式的多个子串内容从原字符串中单独拿出来,并能够给出每个子串的位置。

通过Julia内置的**match()函数或eachmatch()**函数遍可达到这些目的,而提取的信息会保存在类型名为RegexMatch的对象中。

通过dump()函数可查看此对象的内部结构:

image-20201012144231473

每个成员变量(有使用场景)的意义如下:

  • 字段match记录匹配的子串整体内容
  • 字段offset记录匹配的子串整体在原字符串中的偏移
  • 字段captures记录捕捉到的各分组子串内容,即match字段中的字符串里符合圆括号内正则表达式的子串,相当于正则模式中对应的各个组(Group);若捕捕捉结果为空,该字段将为nothing,而offsets值会为0(无效值)
  • 字段offsets记录捕捉到的各分组子串的偏移
  • 字段regex记录原始正则表达式的内容

示例:

image-20201012150351397

2.8.5 常用操作

1、连接

字符串连接的几种方法:

  • String构造函数。不支持元组结构和字符串数组创建。
  • join()函数。不要直接将待连接内容以独立字符串或字符参数的形式传入,否则会得到不可预期的结果。
  • string()函数。直接将结构转为字符串,而不是将内部结构进行连接。
  • * :将字符串或者字符进行前后连接。
  • broadcast()函数。实现多个字符串的连接。必须带 ***** 号,如:broadcast(*, “abc”, “ert”)

辅助函数:repeat(),可以构造内容重复出现的字符串。

2、比较

字符串和字符串,字符与字符是可以进行大小比较的。

字符串与字符是不可以进行大小比较的,但是,字符串和字符是可以进行,!=,== ,===的。因为,是否相等或是否相同运算符本身就不限定操作数的类型。

image-20201012154340540

3、搜索
  • occursin()函数,判断一个字符串是否是另一个字符串的子串。也适用于Char对象 如:occursin(“a”,“abc”)
  • in()函数,判断一个字符是否属于某个字符串(上一个也可以做到)
    • 也可以使用in断言 如:‘a’ in “abc”
    • 也可以使用 ∈ 如:‘a’ ∈ “abc”

从前往后搜索的两个函数:

  • findfirst()
  • findlast()

指定搜索的起始位置的两个函数:

  • findnext()
  • findprev()
4、替换

replace(字符串,字符串中的字符=>新的字符,[count=val])

count可以设定被替换的个数。

新的字符可以使用正则表达式进行表示。

image-20201012161525381

uppercase()函数,转为大写。

5、分割

split()函数用于字符串的分割,和java中的是一样的。

image-20201012162515948

2.8.6 字节数组

字节数组的类型是Array{UInt8, 1}。

如何将字符串解析为字节数组?

  • 在字符串前加一个b 如:b"abc"

如何将字符串对象转为字节数组?

  • Array{UInt8, 1}(s) : s是字符串对象
  • 使用convert()函数。 如:convert(Array{UInt8, 1}, “bytes”)

将字符串转为字节数组的过程中,Julia遵循以下的转换规则:

  • ASCII字符或转义字符作为单字节处理。
  • 数制前缀(如\X 或 \O)生成对应值得字节序列
  • Unicode前缀会输出UTF-8码值的字节序列

2.8.7 字符串与数值之间的转换

数值转字符串:

  • string(数值, base, pad)函数 base代表数制 pad代表字符串对齐

字符串转数值:

  • parse(type, str, base=10) type:结果的数据类型 str :待解析的字符串 base :用于说明数制,默认10进制image-20201012170741865
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值