之前据说过Julia,不过那时候官网还处于时不时宕机状态,最近Julia发布了1.0 released版本处处都是它的资讯,官网良心自带简体中文,趁着热度我也来试试,顺便聊记一二。git
Julia源于用户需求。用户但愿有一门开源的脚本编程语言,有C的高性能,Ruby的灵活,Lisp的宏,Matlab那样亲切的数学表达式符号。它既能够像Python同样做为通用编程语言,也能够像R同样用于统计分析,像Perl同样天然的处理字符串,像Matlab同样强大的线性代数,像Shell同样的胶着其余程序。
简而言之,它什么都想,什么都像...
官方给出的Julia有如下特性(省略了一些):github
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开始的!app
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)
的语法:ide
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 |
---|---|
== |
相等 |
!= , ≠ |
不相等 |
< |
小于 |
<= , ≤ |
小于等于 |
> |
大于 |
>= , ≥ |
大于等于 |
另外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
julia> let i=0,res=0 while i<=100 res +=i i+=1 end println(res) end 5050
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