【ruby on rails】dup、deep_dup、clone的区别

一、区别

  • dup

浅复制:dup 方法创建对象的浅复制。

不复制冻结状态:dup 不会复制对象的冻结状态。

不复制单例方法:dup 不会复制对象的单例方法。

  • deep_dup

深复制:deep_dup 方法创建对象的深复制,递归复制嵌套的对象。

需要手动实现:deep_dup 不是 Ruby 内置的方法,通常需要手动实现或使用 ActiveSupport 提供的实现。

  • clone

浅复制:clone 方法创建对象的浅复制。

复制冻结状态:clone 会复制对象的冻结状态。

复制单例方法:clone 会复制对象的单例方法。

二、示例

  • 浅复制的意思是只复制对象的第一层属性,不会递归复制嵌套的对象。
  • 深复制的意思是递归复制嵌套对象
ruby 复制代码
require 'active_support/core_ext/object/deep_dup'

# 使用 dup
# 这里 original 是一个包含嵌套哈希的哈希。dup 方法只复制了 original 的第一层属性,因此 dup_copy[:b] 和 original[:b] 仍然引用同一个嵌套哈希 { c: 4 }。所以修改 dup_copy[:b][:c] 也会影响 original[:b][:c]
original = { a: [1, 2, 3], b: { c: 4 } }
dup_copy = original.dup
dup_copy[:b][:c] = 5
puts original[:b][:c] # => 5 (浅复制)

original = "hello".freeze
copy = original.dup
copy.frozen? # => false (不复制冻结状态)

# 使用 deep_dup
original = { a: [1, 2, 3], b: { c: 4 } }
deep_dup_copy = original.deep_dup
deep_dup_copy[:b][:c] = 6
puts original[:b][:c] # => 4 (深复制)

# 使用 clone
original = { a: [1, 2, 3], b: { c: 4 } }
clone_copy = original.clone
clone_copy[:b][:c] = 7
puts original[:b][:c] # => 7 (浅复制)

original_str = "hello".freeze
clone_copy = original_str.clone
puts clone_copy.frozen? # => true (复制冻结状态)

三、dup 方法常用场景:通常用于创建对象的浅复制

ruby 复制代码
# 避免修改原始对象
original_array = [1, 2, 3]
copy_array = original_array.dup
copy_array << 4
puts original_array.inspect # => [1, 2, 3]
puts copy_array.inspect     # => [1, 2, 3, 4]

# 复制可变对象
original_hash = { a: 1, b: 2 }
copy_hash = original_hash.dup
copy_hash[:c] = 3
puts original_hash.inspect # => {:a=>1, :b=>2}
puts copy_hash.inspect     # => {:a=>1, :b=>2, :c=>3}

# 复制对象的状态
class MyClass
  attr_accessor :value
end

original = MyClass.new
original.value = 10
copy = original.dup
copy.value = 20
puts original.value # => 10
puts copy.value     # => 20

# 复制 ActiveRecord 对象
original_user = User.find(1)
copy_user = original_user.dup
copy_user.email = "new_email@example.com"
copy_user.save
相关推荐
ZC跨境爬虫14 小时前
海南大学交友平台登录页开发实战day6(覆写接口+Flask 本地链接正常访问)
前端·后端·python·flask·html
花椒技术15 小时前
从 1.5 秒到 660ms,直播间首屏秒开是怎么做出来的?
人工智能·后端·全栈
Rust研习社15 小时前
深入 Rust 引用计数智能指针:Rc 与 Arc 从入门到实战
开发语言·后端·rust
树獭叔叔15 小时前
OpenCLI:让任何网站成为你的命令行工具
后端·aigc·openai
夜悊15 小时前
顺序栈和链栈的C/C++语言描述实现模板
数据结构
峥嵘life15 小时前
Android + Kiro AI软件开发实战教程
android·后端·学习
m0_7167652316 小时前
数据结构--单链表的插入、删除、查找详解
c语言·开发语言·数据结构·c++·笔记·学习·visual studio
石榴树下的七彩鱼16 小时前
Python OCR 文字识别 API 接入完整教程
开发语言·人工智能·后端·python·ocr·api·图片识别
Memory_荒年16 小时前
别让用户“剁手”把你搞破产:接口幂等性与防重的终极防线
后端
掘金者阿豪16 小时前
程序员必踩的一个坑:Codex 报错 Missing environment variable `OPENAI_API_KEY`,完整解决指南(附架构图)
后端