Julia体验 语言基础
以前听说过Julia,不过那时候官网还处于时不时宕机状态,最近Julia发布了1.0 released版本到处都是它的资讯,官网良心自带简体中文,趁着热度我也来试试,顺便聊记一二。
关于Julia
Julia源于用户需求。用户希望有一门开源的脚本编程语言,有C的高性能,Ruby的灵活,Lisp的宏,Matlab那样亲切的数学表达式符号。它既可以像Python一样作为通用编程语言,也可以像R一样用于统计分析,像Perl一样自然的处理字符串,像Matlab一样强大的线性代数,像Shell一样的胶着其他程序。
简而言之,它什么都想,什么都像...
官方给出的Julia有以下特性(省略了一些):
- 快速:Julia可以通过LLVM而跨平台被编译成高效的本地代码。
- 通用:Julia使用多分派作为编程范式,使其很容易表达面向对象和函数式编程范式。
- 动态:Julia是动态类型的,与脚本语言类似
- 数值计算:Julia擅长于数值计算,它的语法适用于数学计算,支持多种数值类型,并且支持并行计算。
- 可选的类型标注:Julia拥有丰富的数据类型描述
- 可组合:Julia的包可以很自然的组合运行。单位数量的矩阵或数据表一列中的货币和颜色可以一起组合使用并且拥有良好的性能。
变量和字符串
Julia内建支持大数运算,不需要调用函数。同时也支持unicode
julia> 83275689127389671289376897238976*895623897689127389068912376897289/3487689234768972893+28358923785-23895728937
-3.4911515696355016e18
julia> unicode_var = "你好,中国"
"你好,中国"
julia> 'g'
'g': ASCII/Unicode U+0067 (category Ll: Letter, lowercase)
julia> λ = "special_variable_name"
"special_variable_name"
julia> λ = "redefine its value since it's a variable"
"redefine its value since it's a variable"
字符串会处理转义字符,如果想保留它们需要在前面加上raw
julia> println("hello\nworld")
hello
world
julia> println(raw"hello\nworld")
hello\nworld
还可以通过下标运算取到对应字符,最后一个字符用end指代,这但是下标居然不是从0开始的!
julia> welcome[0]
ERROR: BoundsError: attempt to access "hello world"
at index [0]
julia> welcome[1]
'h': ASCII/Unicode U+0068 (category Ll: Letter, lowercase)
julia> welcome[end]
'd': ASCII/Unicode U+0064 (category Ll: Letter, lowercase)
还可以使用切片操作welcome[2:4]
获取子字符串ello
。
拼接字符串需要用string(str1,str2.,..)或者*
,不能使用+
。
如果要对字符串进行内部求值(官方术语interpolation),需要使用$(xx)
的语法:
julia> "3+2-5=$(3+2-5)"
"3+2-5=0"
julia> name = "yang"
"yang"
julia> "hello, $name"
"hello, yang"
Julia目标称希望有Perl一样强大的字符串处理能力,那么内建正则表达式算是言出必行的表现。它的正则表达式是Perl兼容的,由PCRE提供,下面示例来自官方文档:
julia> r"^\s*(?:#|$)"
r"^\s*(?:#|$)"
julia> typeof(ans)
Regex
julia> m = match(r"(a|b)(c)?(d)", "acd")
RegexMatch("acd", 1="a", 2="c", 3="d")
julia> m.match
"acd"
julia> m.captures
3-element Array{Union{Nothing, SubString{String}},1}:
"a"
"c"
"d"
常量
常量通过const
关键字指定,不过常量还能重定义,REPL只显示warning并不阻止这样的做法,只有当重定义不同类型值的时候才会提示Error。文档强烈不建议重定义常量值。
julia> const a,b = 2,3
(2, 3)
julia> const a,b = 3,2
WARNING: redefining constant a
WARNING: redefining constant b
(3, 2)
julia> a,b
(3, 2)
julia> const a,b = 3.0,2
ERROR: invalid redefinition of constant a
类型
整型和浮点类型值不依赖于平台,有明确的范围:
Type | Signed? | Number of bits | Smallest value | Largest value |
---|---|---|---|---|
Int8 |
✓ | 8 | -2^7 | 2^7 - 1 |
UInt8 |
8 | 0 | 2^8 - 1 | |
Int16 |
✓ | 16 | -2^15 | 2^15 - 1 |
UInt16 |
16 | 0 | 2^16 - 1 | |
Int32 |
✓ | 32 | -2^31 | 2^31 - 1 |
UInt32 |
32 | 0 | 2^32 - 1 | |
Int64 |
✓ | 64 | -2^63 | 2^63 - 1 |
UInt64 |
64 | 0 | 2^64 - 1 | |
Int128 |
✓ | 128 | -2^127 | 2^127 - 1 |
UInt128 |
128 | 0 | 2^128 - 1 | |
Bool |
N/A | 8 | false (0) |
true (1) |
Type | Precision | Number of bits |
---|---|---|
Float16 |
half | 16 |
Float32 |
single | 32 |
Float64 |
double | 64 |
变量的类型可以通过typeof()
获取,大小可以使用sizeof()
获取,两者可以参数可以是值也可以是数据类型。
julia> typeof([1,2,4])
Array{Int64,1}
julia> typeof(0xcafebabe)
UInt32
julia> λ = "special_variable_name"
"special_variable_name"
julia> typeof(λ)
String
julia> typeof(2e-2)
Float64
julia> typeof(Int)
DataType
julia> typeof(String)
DataType
julia> typeof(true)
Bool
julia> sizeof(2e-2)
8
julia> sizeof(Float16)
2
julia> sizeof(Int16(1024))
2
julia> sizeof("hello")
5
julia> sizeof([1,2,3])
24
运算
Julia主要用于数值优化,科学计算等,表达式贴近数学符号。除了日常四则运算外还有平方运算2^10
,以及一些新奇的运算符:
julia> √4
2.0
julia> √√16
2.0
julia> typeof(√) #看起来开根号是个sqrt的语法糖
typeof(sqrt)
julia> sqrt(4)
2.0
julia> 2(3+2)
10
julia> x=1
julia> x(x+1)#x放到前面会被解析为可调用对象导致出错
ERROR: MethodError: objects of type Int64 are not callable
julia> (x+1)x
2
运算符很多,官方文档已有总结,这里直接复制翻译一下:
算术运算符 | 名称 | 描述 |
---|---|---|
+x |
unary plus | 恒等运算 |
-x |
unary minus | 求相反数 |
x + y |
binary plus | 加法 |
x - y |
binary minus | 减法 |
x * y |
times | 乘法 |
x / y |
divide | 除法 |
x ÷ y |
integer divide | 整数除法,结果保留整数 |
x \ y |
inverse divide | 等价于 y / x |
x ^ y |
power | 平方 |
x % y |
remainder | 求余 |
!x |
negation | !true==false,反之亦然。 只用于bool |
位运算符 | Name |
---|---|
~x |
非 |
x & y |
与 |
x \| y |
或 |
x ⊻ y |
异或(⊻这个符号打出来不容易...) |
x >>> y |
逻辑 右移 |
x >> y |
算术 右移 |
x << y |
逻辑/算术左移 left |
数值比较运算符 | Name |
---|---|
== |
相等 |
!= , [≠ ](@ref !=) |
不相等 |
< |
小于 |
<= , [≤ ](@ref <=) |
小于等于 |
> |
大于 |
>= , [≥ ](@ref >=) |
大于等于 |
另外Julia有一个特性,可以进行链式比较
julia> 1 < x < 6
true
不用像大多数语言x>1 && x<6
那样手动逻辑组合。
之前介绍说Julia希望有像Matlab一样强大的线性代数处理表达能力,当然少不了线性代数运算了。可以使用.Operator
进行向量运算
julia> [1,2,3].^ 2
3-element Array{Int64,1}:
1
4
9
julia> [1,2,3].+ 2
3-element Array{Int64,1}:
3
4
5
julia> [1,2,3].÷ 2
3-element Array{Int64,1}:
0
1
1
最后Julia还支持分数和复数表示,这里就不赘述了,感兴趣的请参见Complex and Rational Numbers
函数和方法
Julia认为函数是一个关联实参tuple和一个返回值的对象。
第一种形式是完整的函数定义:
function add(a,b)
x = a+b
#return x 如果没有return默认返回最后一个表达式求得的值
end
第二种是赋值形式的函数定义
add2(a,b) = a+b
函数在Julia被视作一等公民,可以赋值给变量,可以做参数,也可以返回。
julia> apply = function(func,arg)
func(arg)
end
#269 (generic function with 1 method)
julia> apply(!,false)
true
上面例子中定义了一个匿名函数,即lambda,然后函数!
作为参数传递。lambda还可以arg -> expr_body
进行定义:
julia> lambda = val ->( "$val" * "$val","$val","...")
#317 (generic function with 1 method)
julia> lambda("wow")
("wowwow", "wow", "...")
注意lambda函数体的()
表示tuple,它可以让函数返回多个值。
Julia支持指定参数类型,默认值以及关键字形参
julia> misc = function(a::Int,b::Int=2;flag=true)
a+1,b+2,!flag
end
#341 (generic function with 2 methods)
julia> misc(1,2,flag=false)
(2, 4, true)
这个小标题是函数和方法,那么方法呢?其实在其他很多语言中,方法是面向对象领域的函数的别称。这里Julia给了另一种定义:
It is common for the same conceptual function or operation to be implemented quite differently for different types of arguments: adding two integers is very different from adding two floating-point numbers, both of which are distinct from adding an integer to a floating-point number. Despite their implementation differences, these operations all fall under the general concept of "addition". Accordingly, in Julia, these behaviors all belong to a single object: the + function. To facilitate using many different implementations of the same concept smoothly, functions need not be defined all at once, but can rather be defined piecewise by providing specific behaviors for certain combinations of argument types and counts. A definition of one possible behavior for a function is called a method.
方法是函数更具体的表现形式。如果学过C++那完全可以类比,函数就是模板函数,方法就是特化的函数模板。
控制流
Julia的控制流和其他高级语言基本类似,这里就直接给例子了。
- 复合表达式
julia> z = begin
a=1
b=2
(a+b,a/b)
end
julia> z
(3, 0.5)
- 条件运算
#julia也提供 ?: 三元运算符
if flag && a<b
println("a <b")
elseif flag && a==b
println("a==b")
elseif flag && a<b
println("a>b")
end
- while循环
julia> let i=0,res=0
while i<=100
res +=i
i+=1
end
println(res)
end
5050
- for循环
julia> for i=1:10
print(i," ")
end
1 2 3 4 5 6 7 8 9 10
julia> for name in ["Alice","Andrew","Jane"]
print(name*" ")
end
Alice Andrew Jane
julia> while true
println(i)
global i+=1
if i<5
continue
else
break
end
end
5
- 异常处理
julia> throw("exception")
ERROR: "exception"
Stacktrace:
[1] top-level scope at none:0
...
julia> try
sqrt(-1)
catch y
println(y)
end
DomainError(-1.0, "sqrt will only return a complex result if called with a complex argument. Try sqrt(Complex(x)).")
关于Julia的Task后面我可能会再写一篇文章详细说说。
作用域
模块是现代软件开发必不可少的成分,Julia也提供了对它的支持。使用module end
即可创建一个模块,import
进行导入:
julia> module warehouse
x = 1
y = (arg,val) -> arg(arg(val))
end
WARNING: replacing module warehouse.
Main.warehouse
julia> import .warehouse
julia> warehouse.y(+,2)
2
复合类型
使用struct ... end
进行可以创建一个复合类型,这就是Julia提供的面向对象的方法
struct Novel
name::String
author::String
price::Float64
# 构造函数
Novel(name::String,author::String,price::Float64) = new(name,author,price)
end
function stringify(val::Novel)
print("Novel{",val.name,",",val.author,",",val.price,"}")
end
ff = Novel("Gobacktoearth","yy",56.4)
stringify(ff)
Novel{Gobacktoearth,yy,56.4}
我的博客即将搬运同步至腾讯云+社区,邀请大家一同入驻:https://cloud.tencent.com/developer/support-plan?invite_code=wsp9wvpm612x
Julia体验 语言基础的更多相关文章
- Julia体验 语言特性 元编程,宏
上接语言基础,就release-1.1来看,个人感觉这门语言和自己心中的理想国相距较远.这门语言因为受众不仅仅是程序员有很多让人迷惑的设计,但是奇怪的是它的语法等表象设计虽然暗示这不是专门为程序员准备 ...
- Swift语言指南(一)--语言基础之常量和变量
原文:Swift语言指南(一)--语言基础之常量和变量 Swift 是开发 iOS 及 OS X 应用的一门新编程语言,然而,它的开发体验与 C 或 Objective-C 有很多相似之处. Swif ...
- Go语言基础(一)
Go语言基础(一) 国庆体验一下大名鼎鼎的Go语言,IDE使用IEDA+Go插件,边敲代码边体会,感觉Go语言好酷 一.Hello World 和Java类似,go文件需要一个package包含,代码 ...
- D14——C语言基础学PYTHON
C语言基础学习PYTHON——基础学习D14 20180919内容纲要: 1.html认识 2.常用标签 3.京东html 4.小结 5.练习(简易淘宝html) 1.html初识(HyperText ...
- D13——C语言基础学PYTHON
C语言基础学习PYTHON——基础学习D13 20180918内容纲要: 堡垒机运维开发 1.堡垒机的介绍 2.堡垒机的架构 3.小结 4.堡垒机的功能实现需求 1 堡垒机的介绍 百度百科 随着信息安 ...
- D03-R语言基础学习
R语言基础学习——D03 20190423内容纲要: 1.导入数据 (1)从键盘输入 (2)从文本文件导入 (3)从excel文件导入 2.用户自定义函数 3.R访问MySQL数据库 (1)安装R ...
- 《MSSQL2008技术内幕:T-SQL语言基础》读书笔记(下)
索引: 一.SQL Server的体系结构 二.查询 三.表表达式 四.集合运算 五.透视.逆透视及分组 六.数据修改 七.事务和并发 八.可编程对象 五.透视.逆透视及分组 5.1 透视 所谓透视( ...
- 《MSSQL2008技术内幕:T-SQL语言基础》读书笔记(上)
索引: 一.SQL Server的体系结构 二.查询 三.表表达式 四.集合运算 五.透视.逆透视及分组 六.数据修改 七.事务和并发 八.可编程对象 一.SQL Server体系结构 1.1 数据库 ...
- C#语言基础
第一部分 了解C# C#是微软公司在2000年7月发布的一种全新且简单.安全.面向对象的程序设计语言,是专门为.NET的应用而开发的.体现了当今最新的程序设计技术的功能和精华..NET框架为C#提供了 ...
随机推荐
- 关于SQL结构化查询语言中(+)的用法
一.概述 (+):从符号上理解为添加一些内容进入结果集中,那么自然会问到这么几个问题 1.添加什么内容 2.怎么添加 3.添加到什么结果集中 以下内容将以实例说明上面3个问题. 二.实例 以Oracl ...
- 导入android studio项目,编译失败
使用android studio 打开studio 工程,编译的时候报错: “ INFO - .project.GradleProjectResolver - Gradle project resol ...
- 学习Javascript的书籍(转)
学习Javascript的书籍 作者: 阮一峰 日期: 2008年1月 9日 昨天,ppip同学留言: 你的js主要是用什么材料学的?推荐用哪本教程呢? 我想了一下,发现自己还真的读过不少书.我在 ...
- 深入理解asp.net中的 __doPostBack函数
前段时间做一个.net网站的时候,用到了模拟前端按钮刷新updatePanel进行局部刷新的时候,遇见了这个问题,当时没顾上记下来,查看网上资料,记下来留着以后查看. 很早以前,当我刚接触asp.NE ...
- 在Mac OS里安装和升级Git
在此记录,给自己看,也给别人参考. 进入终端,查看当前Git版本,输入指令:git --version 输入which git回车,可以查看当前git在什么位置 经查,版本:2.10.0,版本较低,为 ...
- java开发中用到的技术(持续更新.....)
一.数据库 1.数据库连接池:当jdbc连接数据库使用DriverManager 获取时,每次向数据库建立连接的时候都要讲connection加载到内存中,当同时使用的用户数量较大时,会造成服务器不堪 ...
- js/jq基础(日常整理记录)-1-纯js格式化时间
一.纯js格式化时间 之前记录了一些,工作中发现的比较常用的使用,就记录一下. 由于很基础,就直接贴出来了,不做分析了. 改造一下Date的原型 Date.prototype.format = fun ...
- idea中解决Error:java: Compilation failed: internal java compiler error的问题
项目中,使用gradle做项目构建,当我们想更改JDK的版本时,报以下错误: Information:Using javac 1.8.0_111 to compile java sourcesInfo ...
- AttributeError: 'module' object has no attribute 'gfile'
While running TensorFlow's classify_image, getting AttributeError: 'module' object has no attribute ...
- HttpGet和HttpPost处理重定向的区别
get方法默认会处理302的重定向,response获取到的页面其实是重定向以后的页面,通过response.getStatusLine(),取到的值是200. 通过设置可以用post方法去请求或者把 ...