Julia面向对象(多重派发)
类是编程语言基本抽象概念,比如实数、整数、字符串等等。一般分成静态和动态的,如果代码根据不同的类可以执行不同的操作,称为Polymorphism(多态的),动态语言一般都是是多态的。 Julia是动态类语言,不过也继承了静态类的高效性,如果不添加类型声明,则值是任意类,如果指定类,可以显著提高计算效率和稳定性。 Julia类型的特点也成为它高效的一个重要原因。Julia的类型系统不支持类似于Python/Cpp那样以对象的成员隐式继承,类之间的继承关系需要明确指定(据说继承了lisp的元编程特点,不过我不懂lisp)。
Julia中的所有实体类都是最终类,它们的父类只可能是抽象类。julia中的类都是面向对象的,只有执行类(run-time type)不存在编译类(compile-time type),只有value含有类型,变量只是值的名字。
Julia 对于不指定类执行默认类型,默认类型是任意类,这样我们就可以非常方便的定义函数。让绝大多数程序可以体会不到类的存在。
f(x,y)=x^2+y^2
后续也可以对默认类型的函数追加声明类型,这样有三个好处:
- julia有极为强大的多重派发功能
- 增加可读性
- 便于发现程序错误
类的声明
类通过::进行声明,可以读作“is an instance of”
function test()x::Int8 = 32endtest() #32typeof(ans) #Int8
function sinc()::Float64if x==0return 1endreturn in(pi*x)/(pi*x)end
类的断言
function sinc()::Float64if x==0return 1endreturn in(pi*x)/(pi*x)endsinc(0)::Int8 #TypeError: typeassert: expected Int8, got Float64
a=8isa(a,Int) #True
丰富的原始类型(位类型)
julia提供丰富的位类型体现专业的计算能力,如Int8 Int16 Int32 Int64 Int128,UInt8… Uint128,Float8…Float128
抽象类
Int8 <: Signed # true
其中<: is a subtype of 用来确定是否子类。
组合类
struct Mystructbaxbay::Int8baz::Float64end
foo = Mystruct("Hello", 64, 3.2)typeof(foo) #Mystruct
fieldnames(Mystruct) # :bax, :bay, :baz
foo.bax #"Hello"foo.bay #64
foo2 = Mystruct(66, 3, 5.5)foo2.bax # 66foo2.bay # 3foo2.baz # 5.5
可见对于未定义类bax,foo和foo2并不冲突。
Julia 的对象一经声明后,默认是不可更改的(immutable)。
mutable struct Barbaxbay::Float64end bar = Bar("Hello", 3.5)bar.bay = 1//12
总结
断言类型
上面说到的三种类型:抽象类,原始类,组合类,实际上是非常相关的,比如都是显式断言,含有名字,含有显式断言的父类,可能含有参数。 因此他们遵循相同的逻辑,这些类都属于同一类 DateType
typeof(Real) #DateTypetypeof(Int) #DateType
类的结合
IntOrString = Union{Int, AbstractString} #Union{ Int, AbstractString}"what" :: IntOrString #"what"1.0 :: IntOrString #Error
类的参数化
对于固定类,如果想调节类型很困难,julia中提供了一个重要特性,就是参数化,所有声明类型(DataType)都可以参数化。
struct Point{T}arg::Tlin::Tend
这样做的好处,我们可以通过Point分别开辟不同的固定组合类
point = Point(2.3,4.5) # Point{Float64}(2.3,4.5)point2 = Point{Int16}{3,4)
Point{Float64} <: Point # True
abstract type Pointy{T} end
Pointy{Float64} <: Pointy #Truestruct Point{T} <: Pointy{T}x::Ty::T
end
元组类
元组和数组不同,元组不可更改,只可以插入和删除。
元组用( )开辟。
typeof(("1",2,3)) #Tuple{String,Int64,Int64}
mytype = Tuple{AbstractString,Vararg{Int}} #Tuple{AbstractString,Vararg{Int64,N} where N}
isa(("1",), mytupletype) #True
mytype = Tuple{AbstractString,Vararg{Int,3}} #Tuple{AbstractString,Int64,Int64,Int64}
UnionAll类
前面讲类的参数化时,有说到当对于有参数化的类,所有参数类都属于该类的子类,例如
Type{Float64} <: Type #True
这里Type就相当于Union{ Type{T} where T} 也就是UnionAll类。例如Ptr可以更精确的写为Ptr{T} where T 表示所有可能的T组成的UnionAll类。
对于多参数情况,如Array{T,N} 可以固定一个,如Array{T, 1} where T代表所有的一维数组构成的类。
Array{T} where T <: Real
对类的操作
由于类本身也是对象,此常规函数也可以做用在类上,比如<:函数就代表了类的包含关系。
isa(1, Int) #Truetypeof(Int) #Datatype type由于是object 仍然拥有type typeof(Union{Real,String}) # Uniontypeof(Union) #dataTypesupertype(Float64) #AbstractFloatsupertype(AbstractFloat) #Realsupertype(Real) #Numbersupertype(Number) #Any
优化默认输出
我们经常有改变类输出风格的需求,这个可以通过重载show函数来完成,比如我给出一个表达复数的组合类,想以极坐标的形式输出
struct Polar{T <: Real} <:Numberr::Tθ::T
end
Base.show(io::IO, z::Polar) = print(io, z.r, " * exp(", z.θ, "im)")
Polar(3.0,4.0) #3.0 * exp(4.0im)
Base.show(io::IO, ::MIME"test/plain", z::Polar{T}) where{T} = print(io, "Polar {$T} complex number:\n ", z)
Polar(3.0,4.0) # Polar{Float64} complex number:3.0 * exp(4.0im)
module gsonstruct Goonameage::Int8endfunction tojson()println("I'am toJson method")return "I'am toJson"endfunction tojsonWith(obj::gson.Goo)println("I'am toJson method with ",obj.name)end
end
以上代码可以直接保存为gson.jl,里面关键字,module struct end function。
Julia不允许在结构体里定义函数,至少目前我没成功过,想要实现Java那种 obj.method()形式的调用,不太可能。(Java Bean 里是可以定义字段和方法的)
但是,julia有module这个神奇的东西。代码里是一个module包含了一个结构体和两个方法。那么如何使用呢?
include("gson.jl")
gson.tojson()
goo=gson.Goo("google",32)
gson.tojsonWith(goo)
到此为止,看代码就应该能懂Julia是如何面向对象了。而且还出现了include这个神奇的关键函数。一股子C语言的浓烈味道会不会把你吸引呢?
多态
struct Kittyname::String
end
+(lhs::Int32, res::Float64) = # ...
这个加法并不属于Int类型也不属于Float,这在数学上很讲得通。总体来讲,用Julia为理论对象进行抽象会非常自然。
很多人都问过我,那么如果我有一些公共的成员需要各个子类型都有怎么办?如何少些重复代码?下面我来讲几种方案,请针对自己的情况去选择
abstract type A end
struct B <: A end
struct C <: A endname(::A) = "no name" # 默认没有名字
name(::B) = "name B" # B 是另外的名字,而C就继承了A的行为
使用Symbol作为标签来分发不同的行为,但是它们共享一个参数类型。
struct A{Tag}name::String
endname(x::A{:boy}) = "the boy's name is $(x.name)"
name(x::A{:girl}) = "the girl's name is $(x.name)"
struct Am1m2name
endname(x::A) = x.namestruct Bm1name
endname(x::B) = x.name
以上经验,总结一下就是:在Julia里行为(behaviour)比其它的事情更加重要。而类型仅仅是用来派发行为的一种标签。
Julia面向对象(多重派发)相关推荐
- 有人说Julia比Python好,还给出了5个理由
Julia 是一种多范式的函数式编程语言,用于机器学习和统计编程.尽管 Python 通常被认为是一种面向对象的编程语言,其实它也是用于机器学习的多范式编程语言.需要注意的是,Julia 语言更多地基 ...
- julia与python对比_有人说Julia比Python好,还给出了5个理由
选自medium 作者:Emmett Boudreau 机器之心编译 参与:杜伟.张倩.肖清 本文作者从速度.通用性.多重派发.适用于 ML 的程度和包管理器 5 个方面阐述了 Julia 语言相较于 ...
- 技术▍Julia 解决了 C++/Python/Matlab 的哪些痛点?
图为使用Julia画出来的图 本文作者|罗秀哲 编辑|布袋熊 36大数据获授权发布 机器学习 高性能 GPU 计算的编程语言 昨天我们推送一篇关于"Julia"的文章:< ...
- 机器学习LDA-基础Julia与Python的实现
最近在看一本名为机器学习公式推导与代码实现的书,书中有用Numpy实现的LDA算法,具体Python代码如下 import numpy as np from sklearn import datase ...
- 全面对比 MATLAB、Julia、Python,谁在科学计算中更胜一筹?
数百种编程语言,各有优劣,各自也都有自己最为适用的场景.那么就科学计算领域而言,主流的 MATLAB.Julia.Python 会有哪些最为独特的优势呢?又存在哪些让开发者无力的缺陷?在本文中,我们将 ...
- python 对比matlab_全面对比 MATLAB、Julia、Python,谁在科学计算中更胜一筹?
原标题:全面对比 MATLAB.Julia.Python,谁在科学计算中更胜一筹? 数百种编程语言,各有优劣,各自也都有自己最为适用的场景.那么就科学计算领域而言,主流的 MATLAB.Julia.P ...
- Julia ---- 为Julia做一下辩解
我写这篇文章的主要目的就是为了给我喜欢的Julia语言一辩,并且指出人们对Julia语言的几个常见的误区. 预警:文章非常长,所以需要希望入坑的人有耐心阅读 文章内容 1.常见误区 2.重新认识Jul ...
- 一个简单的Julia教程
原文链接:点击打开链接 摘要: 当前版本 v0.5 因为在知乎上写的量子计算札记会涉及到使用Julia语言的数值模拟,同时随着中国的Julian越来越多,而之前几个在JuliaCN活跃的老司机最近一直 ...
- xx是一个类型 这在给定的上下文_基于上下文的派发:挂起临时变量内存
最近做一些蒙卡相关的东西,然后遇到有一个可能很多人都会遇到的问题: 把所有的步骤都手写成原地(in-place)操作由于需要自己来保管各种中间变量会很麻烦(增加心智负担),但是用比较正常的方式去写又由 ...
最新文章
- html中加载shp文件,运用shapefile.js解析Shp文件
- 小朋友的视频直播之 nginx-rtmp
- 【量化交易】组合优化三部曲:换手率和alpha模型换手约束下的最优模型时变IC下的多空/多头最优组合换手率
- 网校mysql设计规范_网校数据库设计
- 消息队列入门案例-环境搭建
- php mariadb 查询语法,从PHP调用的查询中的MySQL(MariaDB)执行超时
- windows XP系统下oracle完整卸载过程
- android技术积累,Android开发中积累的一些报错的解决方法
- Canal 1.1.5 启动报错:caching_sha2_password Auth failed
- 5.10地址信息函数
- java post加密_使用Java和PHP的BCrypt,发送加密的密码并对其进行解码 - java
- 教你查看传说中的WPS2005彩蛋
- 系统越用越臃肿,你需要的系统瘦身技巧.
- @media 如何使用?
- 苹果Mac电脑文件夹路径怎么看?“访达”也能显示文件路径
- wordpress博客 qq客服插件
- 从0到1的电商架构应该怎么做?
- 很短,很文艺,很唯美的英语美句
- mr.baidu.com百度官方缩短网址接口网站调用生成制作方法解析
- app模式会被第三方平台模式取代吗_手机 App 不能取代第三方浏览器的原因是什么?...
热门文章
- Linux系统编程7:入门篇之Linux项目自动化构建工具-Make/Makefile的超强使用指南
- LeetCode 215 数组中的第K个最大元素
- 面试题 03.02. 栈的最小值/面试题30. 包含min函数的栈/155. 最小栈
- cuckoo沙箱常见报错总结
- Python url中提取域名(获取域名、获取顶级域名、tldextract)
- Linux查看二进制文件hexeditor
- python 标准库之 glob 介绍(获取文件夹下所有同类文件)
- ssm整合之web.xml配置
- Python实现抓取CSDN博客首页文章列表
- Ubuntu 12.04安装Microsoft lifecam studio摄像头