欧美free性护士vide0shd,老熟女,一区二区三区,久久久久夜夜夜精品国产,久久久久久综合网天天,欧美成人护士h版

首頁綜合 正文
目錄

柚子快報邀請碼778899分享:博客 Ruby設計-高級語法

柚子快報邀請碼778899分享:博客 Ruby設計-高級語法

http://yzkb.51969.com/

一、面向?qū)ο蠡A

1.1 定義

class Point

def initialize(x, y)

@x = x

@y = y

end

end

point = Point.new(0, 1)

puts point.is_a? Point # true

? 其中 initialize 方法充當了構造器,以 @ 開頭的變量是實例變量,也就是說是 Java 中的屬性。

? 我們利用 new 方法創(chuàng)造一個變量,類似于一個工廠方法。如果往深里探究,應該是 new 方法是一個類對象方法,也就是說,Point 可以作為一個類,同時它也是 Class 這個類的一個對象,他作為對象有一個方法是 new 。這個 new 會調(diào)用實例方法(就是 java 中的非靜態(tài)方法) new ,然后完成構造。

? is_a?是一個方法,與 Java 中的 instanceof 類似。只要是這個類或者這個類的子類,都會返回 true ,與之相似的是 kind_of? 。 而如果是 instance_of? 那么就只有該類會返回 true。

1.2 實例方法

1.2.1 to_s

? 轉(zhuǎn)換成字符串的方法,如下

def to_s

"(#{@x}, #{@y})"

end

1.2.2 getter, setter

? 我們可以用常規(guī)的方法定義,沒錯,感覺 ruby 的方法名中可以出現(xiàn)各種特殊字符

# getter

def x

@x

end

def y

@y

end

# setter

def x=(value)

@x = value

end

def y=(value)

@y = value

end

? 這種方法無疑是最好的,因為可以掩蓋內(nèi)部具體的實現(xiàn)細節(jié),不過如果只是普通的 getter, setter 那么其實可以利用元編程的知識,直接用 Module 的方法。

attr_accessor :x, :y

? 所謂的“元編程”就是利用代碼創(chuàng)造代碼,這里就不詳細說了。attr_accessor 是一個 Module 的方法,Class 是 Module 的子類,可能 Point 也是 Module 的子類,所以可以使用這個方法。

1.2.3 operator

? 和 C++ 一樣,Ruby 是可以定義運算符的,而且似乎更加簡潔,跟定義方法一模一樣,這可能是由于 Ruby 的方法聲明中允許特殊字符的存在,而且單參數(shù)調(diào)用時可以不加括號導致的。我們?yōu)?Point 定義三個方法

? 定義加法:

def +(other)

Point.new(@x + other.x, @y + other.y)

end

? 定義負號,這里需要注意,有一個 -@ 的特殊寫法

# negative

def -@

Point.new(-@x, -@y);

end

? 定義數(shù)乘,這里和 C++ 一樣,是沒有辦法寫 3 * point 的,只能寫 point * 3

def *(scalar)

Point.new(@x * scalar, @y * scalar)

end

? 為了解決這個問題,我們可以定義個 coerce 方法,似乎這個方法會在 3.* 的時候使用,然后返回的值會重新調(diào)用 point.* 但是具體的原理就不清楚了。

def coerce(other)

[self, other]

end

? 定義索引訪問:

def [](index)

case index

when 0, -2 then @x

when 1, -1 then @y

when :x, "x" then @x

when :y, "y" then @y

else nil

end

end

? 這個是一個只讀數(shù)組,如果想寫這個東西,需要其他的東西。

1.2.4 iterator

? 我們可以定義迭代器方法 each

class Point

...

def each

yield @x

yield @y

end

include Enumerable

end

? 底下這個 include 很有意思,學名叫做混入。似乎 Enumerable 這個模塊里有很多基于 each 的方法,所以只要混入這個模塊,就可以擁有這一堆的迭代器方法(似乎叫做枚舉器方法更為合適)

pointA.each {|e| puts e}

puts pointA.all? {|e| e == 0}

puts Point.new(0, 0).all? {|e| e == 0}

1.2.5 equal

? 在 Ruby 中一般與 Java 相反,我們用 == 表示內(nèi)容上的相等,而用 eq? 表示同一個引用。所以我們一般需要重寫 == 號

def ==(other)

if other.is_a? Point

@x == x && @y == y

else

false

end

end

? 但是同時我們又在 Hash 結構中,使用的是 eq? 這個方法(所以前面那個約定好沒用),和 Java 一樣,如果 eq? 判斷相等了,hash 就必須判斷相等。所以只要定義了 eq? ,那么就需要定義 hash ,并且滿足前面的條件。

1.2.6 Comparable

? 只要定義了 <=> 就可以獲得一大堆比較符。

include Comparable

def <=>(other)

@x**2 + @y**2 <=> other.x**2 + other.y**2

end

Comparable 也是一個混入模塊。

1.3 類方法

? 對應的是 Java 中的靜態(tài)方法,但是實際上很不一樣。類方法在 ruby 中是類對象的單鍵方法,也就是說,類本身就是一個對象。定義單鍵方法,需要指定方法所屬的對象。如圖所示

class Point

...

def self.sum(*points) # self means the "Point", not the point

x = y = 0

points.each {|p| x += p.x; y += p.y}

Point.new(x, y)

end

end

# single-key

puts "sum = #{Point.sum(pointA, pointB, pointC)}"

1.4 類常量

? 定義在類中的常量,這個對應 Java 中的靜態(tài)常量,如下所示

class Point

...

def initialize(x, y)

end

...

ORIGIN = Point.new(0, 0)

end

puts "Origin = #{Point::ORIGIN}"

Point::UNIT_X = Point.new(1, 0)

puts "Unit x = #{Point::UNIT_X}"

? 有一個很有意思的,就是 ORIGIN 要在 initialize 之后,就很神奇,大概還有聲明先后的問題吧。

1.5 類變量

? 定義在類中的變量,靜態(tài)變量,如下所示

class Point

@@n = 0

@@totalX = 0

@@totalY = 0

...

def initialize(x, y)

@x = x

@y = y

@@n += 1

@@totalX += x

@@totalY += y

end

def self.report

puts "There are #{@@n} points"

puts "total x is #{@@totalX}"

puts "total y is #{@@totalY}"

end

end

Point.report

1.6 方法的可見性

? 默認方法一般都是 public ,除了 initialize 。當然對于全局的方法(就是函數(shù)),他是 Object 的實例私有方法。

? 同樣是三種:

private:沒法用 object.method 或者 self.method 調(diào)用,只能直接 method 使用。這只是定義,如果要解釋的話,那么就是適用于 method 這種寫法的東西,就是其他實例方法。protected:只能在

二、面向?qū)ο蟾唠A

3.1 Struct

? 利用 Struct 類可以快速創(chuàng)造出一個類,我的評價是充滿了神秘,比如說之前實現(xiàn)的 Point

OtherPoint = Struct.new(:x, :y)

class OtherPoint

def +(other)

Point.new(self.x + other.x, self.y + other.y)

end

def to_s

"(#{self.x}, #{self.y})"

end

end

? 感覺 Ruby 十分靈活,可以隨時改變類,而且可以多次改變類,如下所示

OtherPoint = Struct.new(:x, :y)

class OtherPoint

def +(other)

Point.new(self.x + other.x, self.y + other.y)

end

def to_s

"(#{self.x}, #{self.y})"

end

end

otherPointA = OtherPoint.new(4, 3)

puts otherPointA

otherPointA.x = 1

class OtherPoint

undef x=, y=

end

# otherPointA.x = 2 NoMethodError

3.2 打開

? 這個就很本質(zhì)了,就是對于這樣的語句

class SomeClass

...

end

module SomeModule

...

end

? 除了第一次有定義的意思,只有都是有“給原有的東西添磚加瓦的意思”。每次的“打開”,都意味著一種 self 指針的變換和作用域的變化。

3.3 泛化關系

? 基本上所有的類都是 Object 類的子類,Class 是 Module 類的子類,所有的類都是 Class 類的實例化,所有的模塊都是 Module 的實例化 。Kernel 是一個 Module,它混入了 Object ,所以哪里都有他,他似乎提供了基本的方法實現(xiàn)(類似于某種 stdlib)。

? 跟前面的 Struct 類似,也可以有很多神秘的語法

M = Module.new # some module called M

C = Class.new # some class called C

D = Class.new(C){include M} # some C subclass called D, which include M

3.4 include, extend

利用 include 和 extend 都可以進行 Mixin(混入操作),對于 include 就是直接混入到實例上? extend 是混入到類上?

3.5 關系

三、函數(shù)式特征

3.1 block

block 是 一小段代碼,用 {} 包裹, 用 yield 關鍵字調(diào)用。迭代器就是基于這個實現(xiàn)的。

def call_twice

yield

yield

end

call_twice {puts "Hello World"}

? yield 是可以傳參的

def call_twice

yield(1)

yield(2)

end

call_twice { |x| puts "Hello World! #{x}"}

3.2 Proc

3.3 Lambda

柚子快報邀請碼778899分享:博客 Ruby設計-高級語法

http://yzkb.51969.com/

推薦閱讀

評論可見,查看隱藏內(nèi)容

本文內(nèi)容根據(jù)網(wǎng)絡資料整理,出于傳遞更多信息之目的,不代表金鑰匙跨境贊同其觀點和立場。

轉(zhuǎn)載請注明,如有侵權,聯(lián)系刪除。

本文鏈接:http://gantiao.com.cn/post/19172588.html

發(fā)布評論

您暫未設置收款碼

請在主題配置——文章設置里上傳

掃描二維碼手機訪問

文章目錄