Julia 初学者指南(二) | 数据类型与函数基础

唠唠闲话

Julia 是一种高性能的动态编程语言,特别适用于数值分析和计算科学领域。它拥有一个强大的类型系统和灵活的多重分派机制,这使得代码易于编写同时还能保持接近 C 语言的运行速度。此外,Julia 也能无缝调用 C 和 Fortran 库,使得它能充分利用现有的高性能计算资源。
本系列教程旨在带领读者从零开始,逐步深入学习 Julia 编程。无论你是编程新手还是有经验的开发者,这些教程都将为你提供清晰的学习路径和丰富的示例代码,帮助你快速掌握 Julia 的核心技术和高级功能。

上节介绍了 Julia 的安装、配置及常用编译器。本篇将探讨 Julia 中的数据类型和函数,这是编程的基础内容。

相关链接:

  • Julia 短课程(陈久宁) – GitHub 地址

Julia 的交互模式

概览

本节介绍 Julia 的五种交互模式,并重点介绍包管理模式,这五种模式分别为:

模式说明进入方式
Julian 模式执行 Julia 代码的地方默认模式,在其他模式下通过退格键 Backspace 进入
Pkg 模式Julia 装包时使用的模式在 Julian 模式按 ] 进入
Help 文档模式查询文档时使用在 Julian 模式下按 ? 进入
Shell 模式切换到系统命令行在 Julian 模式下按 ; 进入
Debug 模式进入代码调试模式安装 Debugger.jl 后使用

除了 Debug 模式,其他四种模式都会经常用到,进入方式不仅适用于终端,也适用于 Jupyter Notebook 等环境。

基本介绍

四种常见模式:
四种常见模式

  1. 初始进入 Julia 时,显示的模式就是 Julian 模式,左侧是绿色的 julia>,页面显示如下:
    深度截图_选择区域_20220404005125

  2. 在 Julian 模式下,按下 ] 进入 Pkg 模式(包管理模式),如下图:
    深度截图_选择区域_20220404005727

  3. 在任意模式下,按退格键(键盘上的 Backspace)可以回到 Julian 模式。

  4. 在 Julian 模式下,按下 ? 进入 Help 模式,此时输入函数可以查看使用文档:
    深度截图_选择区域_20220404005933

  5. 在 Julian 模式下,按下 ; 进入 Shell 模式,这个接触过 Linux 的应该懂怎么用。

  6. Debug 模式个人目前用得不多,暂略。

包的安装

Julia 中安装工具包的方法很简单,有两种方式,一是使用 Pkg 模式,二是在 Julian 模式下调用 Pkg 模块。

  1. 方法一,输入 ] 进入 Pkg 模式,如下图,左侧括号显示 Julia 的开发环境,@v1.6 代表 Julia 1.6 版本,使用默认环境:
    深度截图_选择区域_20220404011026

  2. 输入 add <包名称> 安装具体模块,比如下图,模块下载到用户主目录的 .julia 下:
    深度截图_选择区域_20220404011715

  3. 方法二,退格回到 Julian 模式,输入 using Pkg 导入包管理模块,再输入 Pkg.add("<包名称>") 安装模块,如下图,注意包名称要用引号包含起来:
    深度截图_选择区域_20220404012113

  4. 包安装完成后,可以用 using <包名称> 测试模块导入。

以上只涉及了 Pkg.add 命令,包管理还有很多常用命令,后续再单独写篇介绍,推荐阅读:Pkg 官方手册,Julia 读文档之包的实战。

Julia 的数据结构

基本语法

在 Julia 中,# 用于注释。为了方便学习,相关知识点都写在代码注释中。

  1. @xxx 是 宏 (macro) 的语法。宏可以实现“利用代码生成代码”。

  2. 演示常用的两种宏:

    • @show 显示运算信息,表达式之间用空格隔开。
    • @info 类似 @show,但以第一个变量为打印信息。
  3. 示例:

    x, y = 1, 2
    @show x + y  # x + y = 3
    @show x + y x - y  # x + y = 3 \n x - y = -1
    @info "记录信息" x y x + y
    

    显示结果:
    result

数据类型

整型和浮点数类型

x = 1
@show typeof(x)  # 默认整型
λ = .1
@show typeof(λ)  # .1 等同于 0.1

输出内容:
2021-10-24 13-49-27 的屏幕截图

  1. Julia 支持使用 LaTeX,比如 λ \lambda λ 通过 \lambda + <TAB> 输入;下标 c i c_i ci 通过 c\_i + <TAB> 输入。
  2. 在 Julia 中,“数值 * 变量”用连接简记,比如 2x 等同于 2 * x

其他数值类型

@show typeof(1 + im)  # im 代表虚数 i
@show typeof(1.0 + 2im)  # 浮点虚数
@show 1 / 0  # 无穷大
@show 0 * Inf  # 不定数
@show typeof(Inf)  # Float64
@show typeof(NaN)  # Float64
@show typeof(pi)  # 无理数
@show typeof(missing)  # 缺失类型,用于统计
@show 2 * missing  # missing
@show typeof(nothing)  # 相当于 Python 的 None

输出内容:
2021-10-24 13-52-53 的屏幕截图

字符相关

@show typeof('c')  # 单引号代表字符
@show typeof("c")  # 双引号代表字符串
@show 'c' == "c"  # 数据结构不同
@show "c"[1] === 'c'  # 字符串用索引取出的数据类型是字符
@show "c"[:] == 'c'  # 切片取出字符串
@show "hello " * "world"  # 字符串拼接用 *
@show "hi" ^ 3  # 字符串复制用 ^
var = 2333
@show "hello $var"  # 使用 $ 插入实际变量
@show "hello $(var / 10)"  # 插入运算结果

输出内容:
2021-10-24 13-55-44 的屏幕截图

字符转数值

使用 parse,不能直接用 IntFloat64

@show parse(Int, "1")  # Int 类型
@show parse(Float64, "1")  # Float 类型

输出内容:
20211025122853

容器数据类型

列向量

使用 [] 得列向量 Vector

@show x = [1, 2, 3]  # Vector (column vector)
@show typeof(x)  # 等同于 Array{Int64, 1}
@show Vector(3:5)  # Vector(3:5) = [3, 4, 5]

输出内容:
深度截图_选择区域_20211025123253

切片规则

左闭右闭,首位索引为1,末位索引为 end

x = [1, 2, 3]
@show x[1:end-1]  # end-1 倒数第二位置
@show x[:]  # 取全部
@show x[:] === x  # 切片创建了新对象

输出内容:
深度截图_选择区域_20211025123048
切片两端留空代表取全部,此时得到的是新对象;和 Python 不同的是,切片不能只写一侧,比如 x[2:]

常用属性

  • size(x): 尺寸,返回 Tuple{Int64} 类型
  • length(x): 长度,类似 Python 的 len
  • eltype(x): 元素类型

矩阵

@show y = [1 2 3]  # 空格分列,分号换行
@show [1 2 3 4; 5 6 7 8]
@show [1 2 3 4
5 6 7 8]  # 支持用换行号换行
@show typeof(y)  # 行向量为矩阵类型
@show size(y)  # 矩阵形状
@show size(x)  # 列向量形状
@show x == y  # false | 矩阵尺寸不同,返回否
@show x' == y  # 向量转置,数据格式化为矩阵,类型相等
@show y' == x  # x 仍是向量,y 是 3*1 矩阵

输出内容:
深度截图_选择区域_20211025123737

元组(不可变类型)

x = (1, 2, 3.)
@show typeof(x)  # 元组会单独记录每个位置的数据结构
@show x = 1, 2, 3.  # 定义时括号可省
@show x, y = 1, 2  # 同 Python 的拆包功能
@show x, y = 1, 2, 3, 4, 5  # 拆包多余部分被丢弃

输出内容:
深度截图_选择区域_20211025123926

容器内使用 ... 展开序列

x = [1, 2, 3]
@show (0, x[2:end]...) [3, x...]

输出内容:
深度截图_选择区域_20211025124048

元组的拆分组合操作运行很快

modify_first!(t::Tuple, x) = (x, t[2:end]...)
t = (1, 2, 3)
@btime modify_first!($t, 0)

20211103142242

字典

注意:初始化后,字典键值类型确定,新键值必须保持类型一致。

# Dict{Any, String} with 3 entries
d = Dict(1 => "item1","2" => "item2",(3, 4) => "item3-4")  # 创建字典
@show d[1]  # 取出元素
d[3] = "item3"  # 新增键值
# d[2] = 2  # 报错,与字符串类型不符
@show typeof(1 => 2)  # 创建使用了 Pair 类型
items = (x => x^2 for x in 1:5)  # 先创建 Pair 
@show d = Dict(items)  # 再生成字典

输出内容:
深度截图_选择区域_20211025124503

命名元组

可以简单理解为不可变的字典类型:

d = (x = "first item", y = "second item") 
@show typeof(d)  # 命名元组
@show d[:x]  # 使用 Symbol 取出元素
@show d.y  # 使用 . 取出函数

注意键名必须是变量,不能为数值之类:
深度截图_选择区域_20211025124633

集合交并补操作

x = [1, 2, 3]
y = [2, 3, 4]
@show setdiff(x, y)  # setdiff(x, y) = [1]
@show union(x, y)  # union(x, y) = [1, 2, 3, 4]
@show intersect(x, y)  # intersect(x, y) = [2, 3]

输出内容:
深度截图_选择区域_20211025124703

列表生成器和迭代器

和 Python 类似:

@info "列表生成器" [i for i in -0.5:0.2:1]
@info "迭代器" (i for i in -0.5:0.2:1)

输出内容:
20211103143826

由于迭代器不需要创建中间变量来存储所有结果,在内存使用上是比较高效的:

clamp(x, lo=0, hi=1) = x < lo ? lo : x > hi ? hi : x
f_list() = Dict([x => clamp(x) for x in -0.5:0.2:1.5])
f_generator() = Dict((x => clamp(x) for x in -0.5:0.2:1.5))
@btime f_list()  # 使用列表生成器
@btime f_generator()  # 使用迭代器

输出内容:
深度截图_选择区域_20211104215458

Julia 的函数

基本使用

  1. 用关键字 function 定义函数:

    # 如果没有 return ,默认返回最后一个变量
    function f(x, y)tmp = x + yreturn tmp
    end
    
  2. 用单行定义函数:

    f(x, y) = x + y
    
  3. 三元表达式 cond ? true_rst : false_rst,注意 ?: 前后要留空格:

    greater(a, b) = a > b ? true : false
    @show greater(1, 2)
    

    深度截图_选择区域_20211025125237

  4. = 预定义参数值:

    f(x, y=10) = x + y
    @show f(1) f(1, 2)  # 使用预定义
    

    深度截图_选择区域_20211025125345
    注意:与 Python 不同,Julia 函数的默认值是在函数调用时确定的,因此如果预定义值为可变对象,下次调用将重新创建,不必担心被修改。

  5. 函数指定参数类型,类似 C++ 的重载:

    f(x::Tuple) = "input tuple"
    f(x::Int) = "input int"
    @show f((1, 2))  # 输入元组
    @show f(1)  # 输入整型
    

    深度截图_选择区域_20211025125351

  6. 可变参数用 ...,类似 Python 的 *

    f(x, y...) = y  # 定义函数
    @show f(1)  # 可变参为空元组
    @show f(1, 2, 3, 4)
    

    深度截图_选择区域_20211025125356

  7. 关键词参数:

    f(x; y, z=10) = x + y + z  # 分号隔开关键字
    @show f(0, y=2)  # z 取默认值,y 用关键字赋值
    # f(1, 2, 3)  # 报错,必须用关键字赋值
    f(x) = 0  # 函数重载只比对关键字前的部分
    @show f(0)  # 函数被重置
    

    深度截图_选择区域_20211025125401

  8. 当函数修改变量信息时,约定上,函数名末尾追加 !

    x = [2, 1]
    sort(x)
    @show x  # x 不变
    sort!(x)
    @show x  # x 改变
    

    深度截图_选择区域_20211025125406
    Julia 编写函数时,可以写两个版本,一个带 ! 允许修改变量,运算速度快;再写一个不带 ! 的版本,通过调用第一个函数来定义。

函数式编程

一等公民

在 Julia 中,函数是“一等公民”(First-class citizen)。在编程语言中,一等公民是指支持所有操作的实体,这些操作通常包括作为参数传递、从函数返回、修改并分配给变量等。比如 int 类型,它支持作为参数传递,可以从函数返回,也可以赋值给变量,因此它是一等公民。类似的,函数作为一等公民,意味着可以把函数赋值给变量或存储在数据结构中,也可以把函数作为其他函数的参数或者返回值。一般来说,函数式编程语言、动态语言和现代编程语言中,函数都会作为一等公民。

Julia 与函数式编程

  1. Julia 里的符号可以当函数来用,比如:

    @show +(1, 2)  # 相当于 1 + 2
    
  2. 高阶函数:

    f = x -> x^2  # 匿名函数
    map(f, 1:5)  # [1, 4, 9, 16, 25] | 函数作用在右侧数据上,返回向量
    map((x, y) -> x + y, 1:5, 6:10)  # [7, 9, 11, 13, 15] | 二元函数
    

    支持输入值为函数的还有 reducemapreduceforeachsumfilter 等。这部分和 MMA 类似,就不仔细介绍了。

  3. do 创建一个匿名函数并将其作为第一个参数传递给函数调用:

    map(1:5) do xreturn x^2
    end
    # 相当于
    function f(x)return x^2
    end
    map(f, 1:5)
    

Curry 化

柯里化,指把接受多个参数的函数变换成接受多个单一参数的函数的技术。

例如 > 是一个二参函数,可以通过指定一参来创建一个新函数:

filter(>(3), 1:10)

这里 >(3) 就是一个柯里化的函数,它接受一个参数,返回一个函数。

一般的,在 Julia 中可以用 Base.Fix1Base.Fix2 来实现柯里化:

f(x, y) = x + y
f1 = Base.Fix1(f, 1)
f1.(1:5)  # [2, 3, 4, 5, 6]

面向对象

和 Mathematica 一样,Julia 不支持面向对象,不能继承方法。但面向对象的很多功能可以用结构体及多重派发替代。

Julia 中的抽象对象,某种程度上可以替代继承的功能,我们下一节会详细介绍。

总结

本节内容,介绍了 Julia 的交互模式,基本的数据结构,函数及函数式编程。这些基础知识将为进一步深入学习 Julia 奠定坚实的基础。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://xiahunao.cn/news/3245859.html

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

Linux网络编程-socket套接字使用详解

1.概念 在Linux中&#xff0c;套接字&#xff08;socket&#xff09;是一种通信机制&#xff0c;用于实现不同进程之间或同一主机上的不同线程之间的数据交换。它是网络编程的基础&#xff0c;允许应用程序通过网络进行通信&#xff0c;也可以在同一台机器上的不同进程间进行通…

【STM32】MPU内存保护单元

注&#xff1a;仅在F7和M7系列上使用介绍 功能&#xff1a; 设置不同存储区域的存储器访问权限&#xff08;管理员、用户&#xff09; 设置存储器&#xff08;内存和外设&#xff09;属性&#xff08;可缓冲、可缓存、可共享&#xff09; 优点&#xff1a;提高嵌入式系统的健壮…

如何将电子书发送到kindle

修改guide Amazon之kindle 修改邮箱 参考&#xff1a; blog 多种方式&#xff1a;如何将电子书发送到kindle

《知识点扫盲 · 学会 WebSocket》

&#x1f4e2; 大家好&#xff0c;我是 【战神刘玉栋】&#xff0c;有10多年的研发经验&#xff0c;致力于前后端技术栈的知识沉淀和传播。 &#x1f497; &#x1f33b; CSDN入驻不久&#xff0c;希望大家多多支持&#xff0c;后续会继续提升文章质量&#xff0c;绝不滥竽充数…

笔记 5 :linux 0.11 注释,函数 copy_mem() , copy_process () , 中断函数 int 80H 的代码框架

&#xff08;38&#xff09;接着介绍一个创建进程时的重要的函数 copy_mem&#xff08;&#xff09; 函数&#xff1a; &#xff08;39&#xff09; 分析另一个关于 fork&#xff08;&#xff09; 的重要的函数 copy_process&#xff08;&#xff09;&#xff0c;与李忠老师的操…

大模型的“幻觉”克星!被低估的RAG技术

1 RAG与大模型、Prompt、微调的关系 本文主要带大家深入学习一下最近AI领域的重要技术RAG&#xff0c;本文致力于用大白话给大家说明白RAG&#xff0c;但是还是需要一些大模型和微调有关的领域名词有一些基本的了解&#xff0c;大家选择性阅读哦!在进行正文学习之前我们先用一…

【内网穿透】打洞笔记

文章目录 前言原理阐述公网sshfrp转发服务 实现前提第一步&#xff1a;第二步第三步第四步 补充第五步&#xff08;希望隧道一直开着&#xff09;sftp传数据&#xff08;嫌云服务器上的网太慢&#xff09; 前言 租了一个云服务器&#xff0c;想用vscode的ssh远程连接&#xff…

数据库中的复合查询

一、基本查询回顾 1、查询工资高于500或岗位为manager的员工&#xff0c;并且名字首字母是J 2、按部门编号升序&#xff0c;工资降序排序 3、用年薪降序排序 4、显示工资最高的员工名字和岗位&#xff08;使用了子查询&#xff09; 5、查询工资高于平均工资的员工 6、按部门查…

kubernetes集群部署elasticsearch集群,包含无认证和有认证模式

1、背景&#xff1a; 因公司业务需要&#xff0c;需要在测试、生产kubernetes集群中部署elasticsearch集群&#xff0c;因不同环境要求&#xff0c;需要部署不同模式的elasticsearch集群&#xff0c; 1、测试环境因安全性要求不高&#xff0c;是部署一套默认配置&#xff1b; 2…

orcad导出pdf 缺少title block

在OrCAD中导出PDF时没有Title Block 最后确认问题在这里&#xff1a; 要勾选上Title Block Visible下面的print

《昇思25天学习打卡营第19天|Diffusion扩散模型》

什么是Diffusion Model&#xff1f; 什么是Diffusion Model? 如果将Diffusion与其他生成模型&#xff08;如Normalizing Flows、GAN或VAE&#xff09;进行比较&#xff0c;它并没有那么复杂&#xff0c;它们都将噪声从一些简单分布转换为数据样本&#xff0c;Diffusion也是从…

46 mysql 客户端拿不到具体的错误信息

前言 这是最近碰到的一个问题 同样的一个 环境的问题, 在正常的 mysql 环境会返回 具体的错误信息, 然后 在我的另外一个环境里面 只能返回一些 unknown error 之类的 十分抽象的环境 然后 我们这里 来看一下 具体的情况 我们这里从 错误的环境 往前推导 来查看 并解决这个…

常见的计算机语言有哪些?

计算机语言用于编写软件和应用程序&#xff0c;各种语言有不同的用途和特点。目前常见的的编程语言有&#xff1a; 1、Java&#xff1b;2、Python&#xff1b;3、JavaScript&#xff1b;4、C&#xff1b;5、C#&#xff1b;6、Swift&#xff1b;7、Go&#xff1b;8、Ruby&#…

Chromium CI/CD 之Jenkins实用指南2024-系统基本配置(二)

1. 引言 在现代软件开发和持续集成/持续部署&#xff08;CI/CD&#xff09;过程中&#xff0c;Jenkins已经成为一款不可或缺的工具。作为一个开源的自动化服务器&#xff0c;Jenkins能够帮助开发团队自动化各种任务&#xff0c;包括构建、测试和部署应用程序。特别是当与Ubunt…

高职综合布线实训室

一、高职综合布线实训室建设背景 随着《国民经济和社会发展第十四个五年规划和2035年远景目标纲要》的深入实施&#xff0c;数字化转型已成为国家发展的核心战略之一&#xff0c;计算机网络技术作为数字化建设的基石&#xff0c;其重要性日益凸显。然而&#xff0c;面对数字时代…

数据可视化在智慧医疗中的重要应用

在现代智慧医疗的推动下&#xff0c;数据可视化技术正日益成为医疗领域的重要工具。通过将复杂的医疗数据转换为直观的图表和图形&#xff0c;数据可视化不仅提升了医疗服务的效率&#xff0c;还极大地改善了患者的就医体验。 在智慧医疗中&#xff0c;数据可视化首先在电子病历…

今日早报 每日精选15条新闻简报 每天一分钟 知晓天下事 7月17日,星期三

每天一分钟&#xff0c;知晓天下事&#xff01; 2024年7月17日 星期三 农历六月十二 1、 三部门&#xff1a;紧急调拨1万件救灾物资支持河南、山东两省做好受灾群众基本生活保障工作。 2、 多部门联合公布无人驾驶试点名单&#xff1a;北京、上海等20个城市&#xff08;联合体…

Cesium能做啥,加载哪些数据源,开源免费用商用吗?这里告诉你。

很多小伙伴对Cesium是什么&#xff0c;一知半解&#xff0c;本文是基础知识的扫盲&#xff0c;为大家分享cesium是什么、能做什么、默认数据是什么&#xff0c;为什么首先要进行数据加载&#xff0c;要加载哪些数据&#xff0c;希望通过这些带你入个门&#xff0c;欢迎点赞评论…

所有权与生命周期:Rust 内存管理的哲学

所有权与生命周期&#xff1a;Rust内存管理的哲学 博主寄语引言&#xff1a;编程语言的内存管理困境与 Rust 的解决方案。所有权基本概念&#xff1a;资源的绝对主权生命周期的理解与应用&#xff1a;编译时的守护神借用与引用的精妙设计&#xff1a;安全与效率的和谐共舞Rust …

服务器基础1

服务器基础复习01 1.环境部署 系统&#xff1a;华为欧拉系统 网络简单配置nmtui 因为华为欧拉系统密码需要复杂度 所以我们可以进入后更改密码 echo 123 | passwd --stdin root也可以 echo "root:123" | chpasswd2.关闭防火墙&#xff0c;禁用SElinux 首先先关…