Julia語言程序基礎


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...


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM