Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> Ruby

精通 Ruby Struct 與 OpenStruct:高效的 Value Objects

Ruby 中的 Struct 是什麼?

Struct 是 Ruby 內建類別,用來建立產生 value objects 的新類別。Value object 用於將相關屬性儲存一起。

舉個例子:

一個 Point 有兩個座標(x 和 y)。

你可以用多種方式表示這個資料。

像這樣:

  • 陣列 [10, 20]
  • 雜湊 { x: 10, y: 10 }
  • 物件 Point.new(10, 20)

如果你會有一個以上的 Point,用物件方法通常是個好習慣。

但是……

你不想只為了儲存這兩個值就建立一整個類別!

用 Struct 解決這個問題。

內容

  • 1 如何在 Ruby 中建立 Structs
    • 1.1 替代方式
    • 1.2 最大好處
  • 2 如何使用 Ruby Structs
  • 3 警告:Structs 可能很棘手
    • 3.1 另一件怪事
  • 4 Ruby 2.5 的關鍵字參數
  • 5 如何使用 OpenStruct
  • 6 Struct vs OpenStruct
  • 7 觀看影片教學
  • 8 結論
    • 8.1 相關

開始吧!

如何在 Ruby 中建立 Structs

你可以呼叫 new 並傳入一組 symbol 來建立 Struct,這些 symbol 會成為這個類別的 instance variables。

它們預設會定義 accessor methods,讀寫都有。

例子:

 Person = Struct.new(:name, :age, :gender) 

現在你可以這樣建立物件:

 john = Person.new "john", 30, "M" david = Person.new "david", 25, "M" 

替代方式

你可能在外面看到另一種建立 structs 的方式。

長這樣:

 class Person < Struct.new(:name, :age, :gender) end 

我不推薦這個。

但如果你在外面看到,現在你知道它幹嘛的了。

最大好處

Struct 的一個好處是你可以直接比較它們,基於它們的屬性。

例子:

 john == john # true 

如果這是一般 Ruby 物件,你得自己定義 == 方法。

這就是我們所謂的 "value object"。

如何使用 Ruby Structs

用 struct 比陣列或雜湊好處之一是你可以用方法存取 struct members。

例如:

 puts john.age # 30 puts david.gender # "M" 

這很有幫助,因為如果你有物件陣列,可以用 max, select, sum 等方法。

例子:

 [john, david].max_by(&:age) 

不錯!

警告:Structs 可能很棘手

Struct 產生的類別另一個注意點是……

它們 不會強制建構式的正確參數數量!

讓我解釋。

用一般類別你會看到這個錯誤:

 ArgumentError: wrong number of arguments (0 for 3) 

但用 Struct 缺少的參數會變成 nil:

 Person.new("peter") # struct Person name="peter", age=nil, gender=nil 

使用 Struct 物件時記住這點!

另一件怪事

看看這個……

 Struct.new(:a).ancestors [#<Class:0x29b1040>, Struct, Enumerable, Object, Kernel, BasicObject] 

這個 #<Class:0x29b1040> 是加在 structs 的匿名類別,也注意到 enumerable 模組,讓你能呼叫 each 和 map 等方法。

Ruby 2.5 的關鍵字參數

假設你從檔案讀取行,每行代表一個項目。

例子:

 200 /login 18:00 404 /bacon 18:03 200 /books 18:04 

如果建立自訂類別會更容易處理這資料。

像這樣:

 LogEntry = Struct.new(:status, :url, :time) LogEntry.new(200, '/books', '18:04') 

但為了讓每個參數代表什麼更清楚,你可能想用關鍵字參數。

好消息!

Ruby 2.5 加入了 Struct 物件的關鍵字參數支援。

用法:

 LogEntry = Struct.new(:status, :url, :time, keyword_init: true) LogEntry.new(status: 200, url: '/books', time: '18:04') 

現在你可以解析檔案並轉換成 LogEntry 物件!

如何使用 OpenStruct

如果你只需要一次性物件,應該考慮用 OpenStruct。

程式碼範例:

 require 'ostruct' cat = OpenStruct.new(color: 'black') puts cat.class puts cat.color 

注意你必須 require 'ostruct' 才能用這個類別。

警告:OpenStruct 很慢,根據 schneems 的 reddit 留言,不應在 production apps 使用。我也找到這篇部落格有基準測試支持這點。

Struct vs OpenStruct

Struct 和 OpenStruct 的差別:

  • Struct 建立 新類別 帶有預定義屬性、等值方法 (==) 和 enumerable
  • OpenStruct 建立 新物件 帶有給定屬性

OpenStruct 是花俏的 Hash 物件,而 Struct 像是從模板建立新類別。

觀看影片教學

結論

你學會了 Ruby Struct 和 OpenStruct!只要了解各自的特殊特性你就沒問題。

精通 Ruby Struct 與 OpenStruct:高效的 Value Objects

現在輪到你練習了 🙂