Julia-lang
新興的Julia語言,Julia 一開始就是為高性能而設計的。 Julia 程序通過 LLVM 編譯成高效的多平台機器碼。
Julia中文社區: https://cn.julialang.org/
Julia的誕生: 一群擁有各種語言豐富編程經驗的Matlab高級用戶,對現有的科學計算編程工具感到不滿——這些軟件對自己專長的領域表現得非常棒,但在其它領域卻非常糟糕。他們想要的是一個開源的軟件,它要像C語言一般快速而又擁有如同Ruby的動態性;要具有Lisp般真正的同像性而又有Matlab般熟悉的數學記號;要像Python般通用、像R般在統計分析上得心應手、像Perl般自然地處理字符串、像Matlab般具有強大的線性代數運算能力、像shell般膠水語言的能力,易於學習而又不讓真正的黑客感到無聊;它應該是交互式的,同時又是編譯型的JIT(Just-In-Time)。
-
julia與傳統動態語言最重要的區別是:
- 核心語言很小:標准庫是使用Julia下的,包括整數運算這樣的基礎運算
- 豐富的基礎類型:既可用於定義和描述對象,也可用於做可選的數據標注
- 通過多重派發,可根據類型的不同,來調用同名函數的不同實現
- 為了不同的參數類型,自動生成高效、專用的代碼
- 接近C語言的性能
Julia 變量
Julia語言中,變量是與某個值關聯的名字。你可以用它來保存一個值
x = 10
x + 1
x = "hello world"
Julia提供了非常靈活的變量命名的策略。變量名是大小寫敏感的,且不包含語義,意思就是說,Julia會根據變量的名字區別對待
julia> x = 1.0 1.0
julia> y = -3 -3
julia> Z = "My string" "My string"
julia> customary_phrase = "Hello world!" "Hello world!"
julia> UniversalDeclarationOfHumanRightsStart = " 人人生而自由,在尊嚴和權利上一律平等。"
- 變量的命名
變量名字必須以英文字母開頭。
命名規范:變量名字采用小寫
用下划線分割命名中的單詞,不鼓勵使用
Type Module類型的名字使用大寫字符開頭,並且大寫字母而不是用下划線分割單詞
函數function 和 宏macro的名字使用小寫,不使用下划線
會對輸入參數進行更改的函數要使用嘆號!結尾
- 數值轉換
Julia支持三種數值轉換
- T(x) 和convert(T, x) 會把x轉換成T類型
- 如果T是浮點類型,轉換的結果就是最近的可表示值,可能會是正無窮大。
- 如果T為整數類型,當x不能由 T 類型表示時,會拋出異常InexactError
字符
char類型的值代表單個字符:他只是帶有特殊文本表示法和適當算術行為的32位原始類型,不能轉換為代表Unicode代碼的數值,
- 字符拼接
text = string("Hello", "World")
println(text)
>>> HelloWorld
# 在Julia中字符串拼接的+號變成了*號
println("test" * "123")
- 計算長度
# 計算字符串的長度
println(length.(text))
>>> 10
- 引用變量進行字符拼接
# 引用變量
println("$text" * "123")
>>> HelloWorld123
- 三引號字符串字面量
str = """
又來到某個港口
我不是一定要你回來
"""
println("xix :$str")
- 常見的操作
# findfirst 獲取字符串中是否有相應的字符 如果有返回第一個匹配到的字符下標
flag = findfirst(isequal('0'), "OOOOOOOOOO0OOOOOOO0oo")
println(flag)
# findfirst 獲取字符串中是否有相應的字符 如果有返回最后一個匹配到的字符下標
flag = findlast(isequal('0'), "OOOOOOOOOO0OOOOOOO0oo")
println(flag)
# findnext 字符串偏移 之后進行匹配 偏移到從第15個開始
flag = findnext(isequal('0'), "OOOOOOOOOO0OOOOOOO0oo", 15)
println(flag)
# 判斷字符是否存在在字符串中 返回bool值
flag = occursin("123", "1233123133")
println(flag)
# 切片拆分 以, 間隔
join(["apples", "bananas", "pineapples"], ", ", " and ") "apples, bananas and pineapples"
函數
在Julia中,函數是將一個參數值元祖映射到返回值的對象。Julia的函數不是說純粹的數學函數,在某種意義上,函數可以改變並受程序的全局狀態的影響。在Julia中定義函數的基本語法是:
- 函數基本語法
function f(x, y)
return x + y
end
println(f(1,2))
# 函數還可以進行縮寫 簡潔語法
foo(x, y) = x * y
println(foo(2,3))
- 函數指定返回類型
function bar(x, y)::Int64
return x * y
end
println(
bar(3, 5))
- 元祖
Julia有一個和函數參數與返回值密切相關的內置數據結構叫元祖。一個元祖是一個固定的長度的容器,可以容納任何值。但是不可以被修改
yuanzu = (1,2,2,3,3)
println(typeof(yuanzu))
>>> NTuple{5, Int64}
- 具名元祖
元祖的元素可以有名字。
x = (a=2, b=2^2)
println(x.a)
# 或者 x[1]
>>> 2
- 多返回值
Julia中一個函數可以返回多個值 ,使用元祖來表示
function foo(a, b)
return a + b, a * b
end
println(foo(2,3))
>>>(5, 6)
- 變參函數
function bar(a, b, x...)
return a, b, x
end
println(bar(1, 2, 3,3,4,4))
>>>(1, 2, (3, 3, 4, 4))
- 日期內置函數
# 導入日期庫
using Dates
println(Date(2021, 1, 10))
# >>> 2021-01-10
println(Date(2021,2))
# >>> 2021-02-01
println(Date(2021))
# >>> 2021-01-01
- 關鍵字參數
# 關鍵字參數
function plot(a, b, c=2)
println("$a, $b, $c")
end
plot(6, 8, 1)
>>> 6, 8, 1
plot(6, 8)
>>> 6, 8, 2
- 函數參數中的Do結構
map([1, 2, 3]) do x
if x < 0&& iseven(x) # iseven功能是判斷這個參數是否被2整除
return 0
elseif x == 0
return 1
else
return x
end
end
# 程序會將map中的值遍歷賦值為x
- Julia讀寫文件操作
open("test.txt", "w") do io
write(io, "123")
end
# convert("需要轉換的類型", 數據data) convert可以將數據轉換成相關的數據
open("test.txt", "r") do io
line = readline(io)
println(line)
end
# 循環讀取字符串 一定要記得if for等語句需要使用end結束
open("test.txt", "r") do io
line = readline(io)
println(line)
for i in line
println(i)
end
end
- 向量化函數的點語法
# 函數向量化的.點語法 a => A list => tsil of => Of strings => 7
test_list = ["a", "list", "of", "strings"] .|> [uppercase, reverse, titlecase, length]
println(test_list)
流程控制
Julia提供了大量的流程控制構件
- 復合表達式:begin 和 ;
z = begin
x=2
y=3
x+y
end
println(z)
z = (x=1; y=2; x+y)
println(z)
- 條件表達式:if - elseif - else 和?:(三元運算符)
# if else 不做太多解釋
if 條件
println
elseif 條件
println
else
println
end
- 短路求值:&& || 和鏈式比較
# and 和 or 也不做太多解釋
• 在表達式 a && b 中,子表達式 b 僅當 a 為 true 的時候才會被執行。
• 在表達式 a || b 中,子表達式 b 僅在 a 為 false 的時候才會被執行。
- 重復執行:循環 while for
# while 循環 從0 到100
i = 0
while i <= 100
println(i)
global i+=1
end
# for 循環從1到100
for i = 1:100
println(i)
end
# 循環列表
for i in [1,2,3]
println(i)
end
- 異常處理 try-catch error 和 throw
當一個意外的報錯發生時,會拋出Exception。下面列出的內置exception會中斷程序的正常運行流程
Exception |
---|
ArgumentError |
BoundsError |
CompositeException |
DimensionMismatch |
DivideError |
DomainError |
EOFError |
ErrorException |
InexactError |
InitError |
InterruptException |
InvalidStateException |
KeyError |
注: 上述為常見的異常 |
- throw函數
throw函數就是Python中的raise 、Go中的panic 主動拋出異常
- try/catch語句
通過try/catch 語句可以測試Exception並優雅的處理可能會破壞程序運行的代碼。
try
# 可能會出現異常的代碼包含在這里
throw(InitError)
catch
println("success")
end
# finally版本
try
throw(InitError)
catch
println("success")
finally
println("finally success")
throw(InitError)
end
- task協程 : yieldto
詳情查看https://www.geek-book.com/src/docs/julia/julia/docs.julialang.org/en/v1/base/parallel/index-2.html
變量作用域
變量的作用於是代碼的一個區域,在這個區域中的這個變量是可見的。給變量划分作用於有助於解決變量命名重復沖突。這個概念是符合直覺的
Julia的變量作用域
作用於結構
結構 | 作用於類型 | Allowed within |
---|---|---|
module , baremodule | 全局 | 全局 |
struct 結構體 | local(soft) | 全局 |
for, while ,try | local(soft) | 全局或局部 |
macro | local(hard) | 全局 |
let ,functions, comprehensions, generators | local(hard) | 全局或局部 |
注:begin塊和if塊不會引入新的作用域塊 |
Julia使用詞法作用域,也就是說一個函數的作用域不會從其調用者的作用域繼承,而從函數定義處的作用於繼承。example
module Bar
x = 1
foo() = x
end
import .Bar
x = -1
println(Bar.foo())
>>> 1
-
全局作用域
每個模塊會引進新的全局作用域,與其他所有模塊的全局作用域分開;無所不包的全局作用域不存在。
模塊可以把其他模塊的變量引入到自己的作用域中,通過using或者import語句或者通過.點符號有這種通路,也就是每個模塊都是所謂的命名空間。
-
let塊
不像局部變量的賦值行為,let語句每次運行都會新建一個變量進行綁定。賦值改變的是已存在值的位置,let會新建新的位置。這個區別通常都不重要,只會在通過閉包跳出作用於的變量的情況下能探測到。let語法接受由逗號隔開的一系列的賦值和變量名:
let x = 1 let local x=2 println(x) end println(x) end
通過for循環或者推倒式的迭代變量始終是一個新的變量:
function f() i = 0 for outer i = 1:3 end println(i) end f()
-
變量
變量的經常的一個使用方式是給一個特定的不變的值一個名字,這樣的變量只會被賦值一次且不能修改,關鍵字為const。const說明只應該在全局作用域中對全局 變量使用。
const c, d = 1, 2 println("a:$c, b:$d")
數據類型
Julia語言系統是動態的,但通過允許指出某些變量具體的數據類型,獲得了靜態類型系統的一些優點。這對於生成高效的代碼非常有幫助,但更重要的是,它允許針對函數參數類型的方法派發與語言深度集成。方法派發將在方法中詳細探討,但他根植於此系統的類型系統。
在類型被省略時,Julia默認行為是允許變量可以為任何類型。因此可以像Python一樣無需明確的聲明變量的數據類型.
類型聲明
:: 運算符可以用來在程序中聲明類型也就是 類型注釋 可以提升性能 , 在某些場景下
println(1+2 :: Int)
function foo()::Int8
# a :: String = "211"
return 122
end
println(typeof(foo()))
>>> Int8
抽象類型
抽象類型不能實例化,只能作為類型圖中的節點使用,從而描述由相關具體類型組成的集合:那些作為其后代的具體類型。
Julia的變量作用域
作用於結構
結構 | 作用於類型 | Allowed within |
---|---|---|
module , baremodule | 全局 | 全局 |
struct 結構體 | local(soft) | 全局 |
for, while ,try | local(soft) | 全局或局部 |
macro | local(hard) | 全局 |
let ,functions, comprehensions, generators | local(hard) | 全局或局部 |
Julia與Python的區別
- 切片 Julia 索引從1開始 Python從0開始
- Python切片左開右閉 julia 左右全閉
- Julia不支持負數索引
- Julia的條件語句 使用end結束 Python是以縮進結束
持續更新ing...