Julia简单教程

10 篇文章 0 订阅
1 篇文章 0 订阅

目录

 

一、基本数据类型和运算符

二、变量和集合

三、控制流

四、函数

五、类型

六、多次调度


一、基本数据类型和运算符

查看数据类型  使用typeof

julia> typeof(3)
Int64

julia> typeof(3.2)
Float64

julia> typeof(2 + 1im)
Complex{Int64}

julia> typeof(2 // 3)
Rational{Int64}

所有正常中缀运算符都可用

julia> 1 + 1
2

julia> 8 - 1
7

julia> 10 * 2
20

julia> 35 / 5
7.0
# 除以整数总是得到浮点64
julia> 10 / 2 
5.0
# 对于截断的结果,请使用div
julia> div(5, 2) 
2

julia> 5 \ 35
7.0
# 幂,不是按位异或
julia> 2^2 
4

julia> 12 % 10
2

用括号强制优先

julia> (1 + 3) * 2
8

Julia(例如与 Python 不同)具有整数下/溢出

julia> 10^19
-8446744073709551616

使用bigint或浮点来避免这种情况

julia> big(10)^19
10000000000000000000

julia> 1e19
1.0e19

julia> 10.0^19
1.0e19

位运算符

# 按位非
julia> ~2
-3
# 按位与
julia> 3 & 5
1
# 按位或
julia> 2 | 4
6
# 按位异或
julia> xor(2, 4)
6
# 逻辑右移
julia> 2 >>> 1
1
# 算数右移
julia> 2 >> 1
1
# 逻辑/算数左移
julia> 2 << 1
4

使用bitstring函数查看数字的二进制表示。

julia> bitstring(12345)
"0000000000000000000000000000000000000000000000000011000000111001"

julia> bitstring(12345.0)
"0100000011001000000111001000000000000000000000000000000000000000"

布尔值是基元

julia> true
true

julia> false
false

布尔运算符

julia> !true
false

julia> !false
true

julia> 1 == 1
true

julia> 2 == 1
false

julia> 1 != 1
false

julia> 2 != 1
true

julia> 1 < 10
true

julia> 1 > 10
false

julia> 2 <= 2
true

julia> 2 >= 2
true
# 比较可以链接起来,就像Python一样,但与许多其他语言不同
julia> 1 < 2 < 3
true

julia> 2 < 3 < 2
false

创建字符串时使用双引号""

julia> "This is a string."
"This is a string."

字符文字用单引号'

julia> 'a'
'a': ASCII/Unicode U+0061 (category Ll: Letter, lowercase)

字符串是 UTF8 编码的,所以像“π”或“☃”这样的字符串并不直接等同于单个字符的数组。

只有当它们只包含 ASCII 字符时,它们才能被安全地索引。

julia> ascii("This is a string")[1]
'T': ASCII/Unicode U+0054 (category Lu: Letter, uppercase)

注意,Julia从1索引所有内容(如MATLAB),而不是0(如大多数语言)。

否则,建议对字符串进行迭代(map、for循环等)

字符串可以按字典顺序进行比较:

julia> "good" > "bye"
true

julia> "good" == "good"
true

julia> "1 + 2 = 3" == "1 + 2 = $(1 + 2)"
true

$(..)可用于字符串插值,你可以把任何Julia表达式放在括号里。:

julia> "2 + 2 = $(2 + 2)"
"2 + 2 = 4"

打印很容易

julia> println("I'm Julia. Nice to meet you!")
I'm Julia. Nice to meet you!

另一种格式化字符串的方法是stdlib printf中的printf宏。

# 这就是加载(或导入)模块的方式
julia> using Printf
julia> @printf "%d is less than %f\n" 4.5 5.3
5 is less than 5.300000

二、变量和集合

在赋值给变量之前不需要声明变量。

julia> someVar = 5
5

julia> someVar
5

访问以前未分配的变量是一个错误

try
    someOtherVar
catch e
    println(e)
end

输出:

UndefVarError(:someOtherVar)

变量名以字母或下划线开头。之后,您可以使用字母、数字、下划线和感叹号。

julia> SomeOtherVar123! = 6
6

您还可以使用某些unicode字符

这里☃ 是Unicode的“雪人”字符,请参见http://emojipedia.org/%E2%98%83%EF%B8%8F 如果这里显示错误

julia> ☃ = 8
8

这些对于数学符号尤其方便,比如常数π

julia> 2 * π
6.283185307179586

关于Julia中命名约定的注释:

分词可以用下划线('''')表示,但不鼓励使用下划线,除非名称很难读懂

类型名称以大写字母开头,单词之间用大小写分隔,而不是下划线。

函数和宏的名称用小写,不带下划线。

修改其输入的函数的名称以!结尾。这些函数有时称为变异mutating函数或就地in-place函数。

 

数组存储由整数1到n索引的一系列值:

julia> a = Int64[]
0-element Array{Int64,1}

一维数组文字可以用逗号分隔的值编写。

julia> b = [4, 5, 6]
3-element Array{Int64,1}:
 4
 5
 6

julia> b = [4; 5; 6]
3-element Array{Int64,1}:
 4
 5
 6

julia> b[1]
4
# 使用b[-1]会报错
julia> b[end]
6

二维数组使用空格分隔的值和分号分隔的行。

julia> matrix = [1 2; 3 4]
2×2 Array{Int64,2}:
 1  2
 3  4

特定类型的数组

julia> b = Int8[4, 5, 6]
3-element Array{Int8,1}:
 4
 5
 6

使用push!和append!将内容添加到列表的末尾!

按照惯例,感叹号“!”附加到函数名之后,表示会修改他们的参数

julia> push!(a, 1)
1-element Array{Int64,1}:
 1

julia> push!(a, 2)
2-element Array{Int64,1}:
 1
 2

julia> push!(a, 4)
3-element Array{Int64,1}:
 1
 2
 4

julia> push!(a, 3)
4-element Array{Int64,1}:
 1
 2
 4
 3

julia> append!(a, b)
7-element Array{Int64,1}:
 1
 2
 4
 3
 4
 5
 6

用pop从末端移除

julia> pop!(b)
6

julia> b
2-element Array{Int8,1}:
 4
 5

我们把它放回去吧

julia> push!(b, 6)
3-element Array{Int8,1}:
 4
 5
 6

julia> b
3-element Array{Int8,1}:
 4
 5
 6

记住Julia从1索引,而不是从0索引!

julia> a[1]
1

end是最后一个索引的缩写。它可以用于任何索引表达式

julia> a[end]
6

我们还有popfirst!和pushfirst!

julia> popfirst!(a)
1

julia> a
6-element Array{Int64,1}:
 2
 4
 3
 4
 5
 6

julia> pushfirst!(a, 7)
7-element Array{Int64,1}:
 7
 2
 4
 3
 4
 5
 6

以感叹号结尾的函数名表示它们修改了参数。

julia> arr = [5,4,6]
3-element Array{Int64,1}:
 5
 4
 6

julia> sort(arr)
3-element Array{Int64,1}:
 4
 5
 6

julia> arr
3-element Array{Int64,1}:
 5
 4
 6

julia> sort!(arr)
3-element Array{Int64,1}:
 4
 5
 6

julia> arr
3-element Array{Int64,1}:
 4
 5
 6

查看数组之外的下标,会报越界错误。

try
    a[0] # => BoundsError([7, 2, 4, 3, 4, 5, 6], (0,))
    a[end + 1] # => BoundsError([7, 2, 4, 3, 4, 5, 6], (8,))
catch e
    println(e)
end

错误列出它们来自的行和文件,即使它在标准库中。您可以在julia文件夹中的share/julia文件夹中查找这些文件。

可以从range初始化数组。

julia> a = [1:5;]
5-element Array{Int64,1}:
 1
 2
 3
 4
 5

julia> a2 = [1:5]
1-element Array{UnitRange{Int64},1}:
 1:5

可以使用slice语法查看range。

julia> arr = [3,4,5]
3-element Array{Int64,1}:
 3
 4
 5
#减掉数组arr中下标为2的数值
julia> splice!(arr, 2)
4

julia> arr
2-element Array{Int64,1}:
 3
 5

用append!连接列表

julia> b = [1,2,3]
3-element Array{Int64,1}:
 1
 2
 3

julia> append!(a, b)
8-element Array{Int64,1}:
 1
 2
 3
 4
 5
 1
 2
 3

julia> a
8-element Array{Int64,1}:
 1
 2
 3
 4
 5
 1
 2
 3

用in检查列表中是否存在

julia> in(1, a)
true

用length检验长度

julia> length(a)
8

元组是不可变的。

julia> tup = (1, 2, 3)
(1, 2, 3)

julia> typeof(tup)
Tuple{Int64,Int64,Int64}

julia> tup[1]
1
tup = (1, 2, 3)
try
    tup[1] = 3 # => MethodError(setindex!, ((1, 2, 3), 3, 1), 0x00000000000068a2)
catch e
    println(e)
end

许多数组函数也处理元组

julia> length(tup)
3

julia> tup[1:2]
(1, 2)

julia> in(2, tup)
true

可以将元组解压为变量

julia> a, b, c = (1, 2, 3)
(1, 2, 3)

julia> a
1

julia> b
2

julia> c
3

即使不使用括号,也会创建元组

julia> d, e, f = 4, 5, 6
(4, 5, 6)

julia> d
4

julia> e
5

julia> f
6

1元素元组与它包含的值不同

julia> (1,) == 1
false

julia> (1) == 1
true

看看交换两个值是多么容易

julia> e, d = d, e  # => (5,4)
(4, 5)

julia> d  # => 5
5

julia> e
4

字典存储映射

julia> emptyDict = Dict()
Dict{Any,Any} with 0 entries

可以使用文本创建字典

julia> filledDict = Dict("one" => 1, "two" => 2, "three" => 3)
Dict{String,Int64} with 3 entries:
  "two"   => 2
  "one"   => 1
  "three" => 3

用[]查找值

julia> filledDict["one"]
1

获取所有keys

julia> keys(filledDict)
Base.KeySet for a Dict{String,Int64} with 3 entries. Keys:
  "two"
  "one"
  "three"

获取所有values

julia> values(filledDict)
Base.ValueIterator for a Dict{String,Int64} with 3 entries. Values:
  2
  1
  3

使用in、haskey检查字典中是否存在键

julia> in(("one" => 1), filledDict)
true

julia> in(("two" => 3), filledDict)
false

julia> haskey(filledDict, "one")
true

julia> haskey(filledDict, 1)
false

试图查找不存在的密钥将引发错误

try
           filledDict["four"]  # => ERROR: KeyError: key "four" not found
       catch e
           println(e)
       end
KeyError("four")

使用get方法通过提供默认值get(dictionary、key、defaultValue)来避免该错误

julia> get(filledDict, "one", 4)
1

julia> get(filledDict, "four", 4)
4

使用集合表示无序、唯一值的集合

julia> emptySet = Set()
Set(Any[])

用值初始化集合

julia> filledSet = Set([1, 2, 2, 3, 4])
Set([4, 2, 3, 1])

向集合中添加更多值

julia> push!(filledSet, 5)
Set([4, 2, 3, 5, 1])

检查值是否在集合中

julia> in(2, filledSet)
true

julia> in(10, filledSet)
false

有集合交集、并集和差集的函数。

julia> otherSet = Set([3, 4, 5, 6])
Set([4, 3, 5, 6])

julia> intersect(filledSet, otherSet)
Set([4, 3, 5])

julia> union(filledSet, otherSet)
Set([4, 2, 3, 5, 6, 1])

julia> setdiff(Set([1,2,3,4]), Set([2,3,5]))
Set([4, 1])

三、控制流

让我们做一个变量

julia> someVar = 5
5

这是一个if语句。缩进在Julia中没有意义。

someVar = 5
if someVar > 10
    println("someVar is totally bigger than 10.")
elseif someVar < 10    # This elseif clause is optional.
    println("someVar is smaller than 10.")
else                    # The else clause is optional too.
    println("someVar is indeed 10.")
end

For循环在iterables上迭代。Iterable类型包括Range、Array、Set、Dict和AbstractString

for animal = ["dog", "cat", "mouse"]
    println("$animal is a mammal")
    # 可以使用$将变量或表达式插入字符串中。
    # 在这种特殊情况下,不需要括号:$animal和$(animal)给出相同的值
end
# => dog is a mammal
# => cat is a mammal
# => mouse is a mammal

你可以用“in”代替“=”。

for animal in ["dog", "cat", "mouse"]
    println("$animal is a mammal")
end
# => dog is a mammal
# => cat is a mammal
# => mouse is a mammal

字典迭代(元组版)

for pair in Dict("dog" => "mammal", "cat" => "mammal", "mouse" => "mammal")
    from, to = pair
    println("$from is a $to")
end
# => mouse is a mammal
# => cat is a mammal
# => dog is a mammal

字典迭代(键值对版)

for (k, v) in Dict("dog" => "mammal", "cat" => "mammal", "mouse" => "mammal")
    println("$k is a $v")
end
# => mouse is a mammal
# => cat is a mammal
# => dog is a mammal

While循环在条件为真时循环

let x = 0
    while x < 4
        println(x)
        x += 1  # Shorthand for in place increment: x = x + 1
    end
end
# => 0
# => 1
# => 2
# => 3

使用try/catch块处理异常

try
    error("help")
catch e
    println("caught it $e")
end
# => caught it ErrorException("help")

四、函数

关键字“function”创建新函数,模板:

function name(arglist)
  body...
end

例子:

function add(x, y)
    println("x is $x and y is $y")
    # 函数返回最后一条语句的值
    x + y
end
julia> add(5, 6)
x is 5 and y is 6
11

函数的紧凑赋值

julia> f_add(x, y) = x + y
f_add (generic function with 1 method)

julia> f_add(3, 4)
7

函数还可以将多个值作为元组返回

julia> fn(x, y) = x + y, x - y
fn (generic function with 1 method)

julia> fn(3, 4)
(7, -1)

可以定义采用可变数量位置参数的函数

function varargs(args...)
    return args
    # 使用关键字return返回函数中的任意位置
end
julia> varargs(1, 2, 3)
(1, 2, 3)

...被称为splat。

我们只是在函数定义中使用它。

也可以在函数调用中使用,

它将数组或元组的内容放入参数列表。

julia> add([5,6]...) # 这相当于加上(5,6)
x is 5 and y is 6
11
julia> x = (5, 6)
(5, 6)

julia> add(x...) # 这相当于加上(5,6)
x is 5 and y is 6
11

可以使用可选的位置参数定义函数

function defaults(a, b, x=5, y=6)
    return "$a $b and $x $y"
end
julia> defaults('h', 'g')
"h g and 5 6"

julia> defaults('h', 'g', 'j')
"h g and j 6"

julia> defaults('h', 'g', 'j', 'k')
"h g and j k"
try
    defaults('h')  # => ERROR: MethodError: no method matching defaults(::Char)
    defaults()  # => ERROR: MethodError: no method matching defaults()
catch e
    println(e)
end

可以定义采用关键字参数的函数,调用时要注明该参数的名字——注意要分号;

function keyword_args(;k1=4, name2="hello")  # note the ;
    return Dict("k1" => k1, "name2" => name2)
end
julia> keyword_args(name2="ness")
Dict{String,Any} with 2 entries:
  "name2" => "ness"
  "k1"    => 4

julia> keyword_args(k1="mine")
Dict{String,String} with 2 entries:
  "name2" => "hello"
  "k1"    => "mine"

julia> keyword_args()
Dict{String,Any} with 2 entries:
  "name2" => "hello"
  "k1"    => 4

可以在同一个函数中组合各种参数

function all_the_args(normalArg, optionalPositionalArg=2; keywordArg="foo")
    println("normal arg: $normalArg")
    println("optional arg: $optionalPositionalArg")
    println("keyword arg: $keywordArg")
end
julia> all_the_args(1, 3, keywordArg=4)
normal arg: 1
optional arg: 3
keyword arg: 4

Julia有头等函数:函数可以被当作变量一样用——

  1. 可以被当作参数传递给其他函数
  2. 可以作为另一个函数的返回值
  3. 还可以被赋值给一个变量
function create_adder(x)
    adder = function (y)
        return x + y
    end
    return adder
end

这是用于创建匿名函数的“刺伤lambda语法”

julia> (x -> x > 2)(3)
true

此函数与上面创建加法器实现相同。

function create_adder(x)
    y -> x + y
end

如果需要,还可以命名内部函数

function create_adder(x)
    function adder(y)
        x + y
    end
    adder
end
julia> add_10 = create_adder(10)
(::var"#adder#23"{Int64}) (generic function with 1 method)

julia> add_10(3)
13

有内置的高阶函数map和filter

julia> map(add_10, [1,2,3])
3-element Array{Int64,1}:
 11
 12
 13

julia> filter(x -> x > 5, [3, 4, 5, 6, 7])
2-element Array{Int64,1}:
 6
 7

我们可以使用列表理解

julia> [add_10(i) for i = [1, 2, 3]]
3-element Array{Int64,1}:
 11
 12
 13

julia> [add_10(i) for i in [1, 2, 3]]
3-element Array{Int64,1}:
 11
 12
 13

julia> [x for x in [3, 4, 5, 6, 7] if x > 5]
2-element Array{Int64,1}:
 6
 7

五、类型

Julia有一套类型系统。

每个值都有一个类型;变量本身没有类型。

可以使用“typeof”函数获取值的类型

julia> typeof(5)
Int64

# 类型是第一级别的值
# DataType表示类型的类型,包括其本身。
julia> typeof(Int64)
DataType

julia> typeof(DataType)
DataType

类型用于文档、优化和分派。它们不是静态检查的。

用户可以定义类型,它们就像其他语言中的记录或结构。使用“struct”关键字定义新类型。

模板:

struct Name
  field::OptionalType
  ...
end

例子:

struct Tiger
    taillength::Float64
    coatcolor # 不包括类型注释与 '::Any相同'
end

默认构造函数的参数是类型的属性,按它们在定义中列出的顺序排列

julia> tigger = Tiger(3.5, "orange")
Tiger(3.5, "orange")

type兼作该类型值的构造函数

sherekhan = typeof(tigger)(5.6, "fire")

这些结构样式类型称为具体类型

它们可以实例化,但不能有子类型。

另一种类型是抽象类型。

抽象名称

abstract type Cat end  # 是类型层次结构中的一个名称和点

抽象类型不能实例化,但可以有子类型。例如,Number是抽象类型。

julia> subtypes(Number)
2-element Array{Any,1}:
 Complex
 Real

julia> subtypes(Cat)
0-element Array{Any,1}

顾名思义,AbstractString也是一种抽象类型

julia> subtypes(AbstractString)
4-element Array{Any,1}:
 String
 SubString
 SubstitutionString
 Test.GenericString

每种类型都有一个超级类型;使用“supertype”函数获取它。

julia> typeof(5)
Int64

julia> supertype(Int64)
Signed

julia> supertype(Signed)
Integer

julia> supertype(Integer)
Real

julia> supertype(Real)
Number

julia> supertype(Number)
Any

julia> supertype(supertype(Signed))
Real

julia> supertype(Any)
Any
# 除了Int64之外,所有这些类型都是抽象的。
julia> typeof("fire")
String

julia> supertype(String)
AbstractString
# 同样的,这里是字符串
julia> supertype(SubString)
AbstractString

<:是子类型运算符(继承)

struct Lion <: Cat  # Lion是Cat的一个子类
    maneColor
    roar::AbstractString
end

可以为您的类型定义更多构造函数

只需定义一个与类型同名的函数

并调用现有构造函数以获取正确类型的值

这是一个外部构造函数,因为它在类型定义之外

Lion(roar::AbstractString) = Lion("green", roar)

像Panther一样,使用内部构造函数可以控制如何创建类型的值。

struct Panther <: Cat  # Panther is also a subtype of Cat
    eyeColor
    Panther() = new("green")
    # Panthers will only have this constructor, and no default constructor.
end

如果可能,应该使用外部构造函数而不是内部构造函数。

六、多次调度

在Julia中,所有命名函数都是泛型函数

这意味着它们是由许多小方法组成的

Lion的每个构造函数都是泛型函数Lion的一个方法。

对于一个非构造函数示例,让我们创建一个函数meow:

狮子、豹、虎的定义

function meow(animal::Lion)
    animal.roar  # access type properties using dot notation
end

function meow(animal::Panther)
    "grrr"
end

function meow(animal::Tiger)
    "rawwwr"
end

测试neow函数

meow(tigger)  # => "rawwwr"
meow(Lion("brown", "ROAAR"))  # => "ROAAR"
meow(Panther()) # => "grrr"

查看本地类型的层次结构

Tiger   <: Cat  # => false
Lion    <: Cat  # => true
Panther <: Cat  # => true

定义一个函数使用cat参数

function pet_cat(cat::Cat)
    println("The cat says $(meow(cat))")
end
pet_cat(Lion("42")) # => The cat says 42
try
    pet_cat(tigger) # => ERROR: MethodError: no method matching pet_cat(::Tiger)
catch e
    println(e)
end

在面向对象语言中,单一分派是常见的;

这意味着根据第一个参数的类型选择方法。

在Julia中,所有参数类型都有助于选择最佳方法。

 

让我们定义一个有更多参数的函数,这样我们就可以看到它们的区别

function fight(t::Tiger, c::Cat)
    println("The $(t.coatcolor) tiger wins!")
end
fight(tigger, Panther())  # => The orange tiger wins!
fight(tigger, Lion("ROAR")) # => The orange tiger wins!

当猫是狮子的时候,让我们改变一下行为

fight(t::Tiger, l::Lion) = println("The $(l.maneColor)-maned lion wins!")
fight(tigger, Panther())  # => The orange tiger wins!
fight(tigger, Lion("ROAR")) # => The green-maned lion wins!

我们不需要老虎来战斗

fight(l::Lion, c::Cat) = println("The victorious cat says $(meow(c))")
fight(Lion("balooga!"), Panther())  # => The victorious cat says grrr
try
    fight(Panther(), Lion("RAWR"))  
    # => ERROR: MethodError: no method matching fight(::Panther, ::Lion)
    # => Closest candidates are:
    # =>   fight(::Tiger, ::Lion) at ...
    # =>   fight(::Tiger, ::Cat) at ...
    # =>   fight(::Lion, ::Cat) at ...
    # => ...
catch e
    println(e)
end

也让猫放在前面的参数位置

fight(c::Cat, l::Lion) = println("The cat beats the Lion")

这个警告是因为还不清楚哪场战斗会被召唤:

try
    fight(Lion("RAR"), Lion("brown", "rarrr"))
    # => ERROR: MethodError: fight(::Lion, ::Lion) is ambiguous. Candidates:
    # =>   fight(c::Cat, l::Lion) in Main at ...
    # =>   fight(l::Lion, c::Cat) in Main at ...
    # => Possible fix, define
    # =>   fight(::Lion, ::Lion)
    # => ...
catch e
    println(e)
end

在其他版本的Julia中,结果可能不同

fight(l::Lion, l2::Lion) = println("The lions come to a tie") 
# => fight (generic function with 5 methods)
fight(Lion("RAR"), Lion("brown", "rarrr"))  # => The lions come to a tie

在引擎盖下,您可以查看llvm和生成的汇编代码。

square_area(l) = l * l  # square_area (generic function with 1 method)

square_area(5)  # => 25

当我们给平方面积输入一个整数时会发生什么?

code_native(square_area, (Int32,), syntax = :intel)
    #         .text
    # ; Function square_area {
    # ; Location: REPL[116]:1       # Prologue
    #         push    rbp
    #         mov     rbp, rsp
    # ; Function *; {
    # ; Location: int.jl:54
    #         imul    ecx, ecx      # Square l and store the result in ECX
    # ;}
    #         mov     eax, ecx
    #         pop     rbp           # Restore old base pointer
    #         ret                   # Result will still be in EAX
    #         nop     dword ptr [rax + rax]
    # ;}

code_native(square_area, (Float32,), syntax = :intel)
    #         .text
    # ; Function square_area {
    # ; Location: REPL[116]:1
    #         push    rbp
    #         mov     rbp, rsp
    # ; Function *; {
    # ; Location: float.jl:398
    #         vmulss  xmm0, xmm0, xmm0  # Scalar single precision multiply (AVX)
    # ;}
    #         pop     rbp
    #         ret
    #         nop     word ptr [rax + rax]
    # ;}

code_native(square_area, (Float64,), syntax = :intel)
    #         .text
    # ; Function square_area {
    # ; Location: REPL[116]:1
    #         push    rbp
    #         mov     rbp, rsp
    # ; Function *; {
    # ; Location: float.jl:399
    #         vmulsd  xmm0, xmm0, xmm0  # Scalar double precision multiply (AVX)
    # ;}
    #         pop     rbp
    #         ret
    #         nop     word ptr [rax + rax]
    # ;}

请注意,如果,参数是浮点数。我们来计算一个圆的面积

circle_area(r) = pi * r * r     # circle_area (generic function with 1 method)
circle_area(5)  # 78.53981633974483

对应汇编代码

code_native(circle_area, (Int32,), syntax = :intel)
    #         .text
    # ; Function circle_area {
    # ; Location: REPL[121]:1
    #         push    rbp
    #         mov     rbp, rsp
    # ; Function *; {
    # ; Location: operators.jl:502
    # ; Function *; {
    # ; Location: promotion.jl:314
    # ; Function promote; {
    # ; Location: promotion.jl:284
    # ; Function _promote; {
    # ; Location: promotion.jl:261
    # ; Function convert; {
    # ; Location: number.jl:7
    # ; Function Type; {
    # ; Location: float.jl:60
    #         vcvtsi2sd       xmm0, xmm0, ecx     # Load integer (r) from memory
    #         movabs  rax, 497710928              # Load pi
    # ;}}}}}
    # ; Function *; {
    # ; Location: float.jl:399
    #         vmulsd  xmm1, xmm0, qword ptr [rax] # pi * r
    #         vmulsd  xmm0, xmm1, xmm0            # (pi * r) * r
    # ;}}
    #         pop     rbp
    #         ret
    #         nop     dword ptr [rax]
    # ;}

code_native(circle_area, (Float64,), syntax = :intel)
    #         .text
    # ; Function circle_area {
    # ; Location: REPL[121]:1
    #         push    rbp
    #         mov     rbp, rsp
    #         movabs  rax, 497711048
    # ; Function *; {
    # ; Location: operators.jl:502
    # ; Function *; {
    # ; Location: promotion.jl:314
    # ; Function *; {
    # ; Location: float.jl:399
    #         vmulsd  xmm1, xmm0, qword ptr [rax]
    # ;}}}
    # ; Function *; {
    # ; Location: float.jl:399
    #         vmulsd  xmm0, xmm1, xmm0
    # ;}
    #         pop     rbp
    #         ret
    #         nop     dword ptr [rax + rax]
    # ;}

 

 

 

  • 0
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值