Ruby 2.4

Struct

class Struct

父类:ObjectIncluded模块:Enumerable

Struct是一种使用访问器方法将多个属性捆绑在一起的简便方法,无需编写显式类。

Struct类生成包含一组成员及其值的新子类。对于每个成员,创建一个类似于Module#attr_accessor的读写器方法。

Customer = Struct.new(:name, :address) do def greeting "Hello #{name}!" end end dave = Customer.new("Dave", "123 Main") dave.name #=> "Dave" dave.greeting #=> "Hello Dave!"

有关创建结构子类和实例的更多示例,请参阅:: new。

在后面的方法描述中,“成员”参数指的是一个结构成员,它是一个带引号的字符串("name")或一个符号(:name)。

常量

组是一个Struct,只有在编译时才可用HAVE_GETGRENT

该结构包含以下成员:

名字

以String形式包含组的名称。

passwd

包含加密密码作为字符串。如果组的密码访问不可用,则返回'x'; 如果不需要密码来获取组的成员资格,则返回空字符串。

必须与编译HAVE_STRUCT_GROUP_GR_PASSWD

gid

包含组的数字ID作为整数。

mem

是包含组成员简短登录名的字符串数组。

Passwd

Passwd

Passwd是包含以下成员的Struct:

name

包含用户的短登录名作为字符串。

passwd

包含用户的加密密码作为字符串。如果正在使用阴影密码,则会返回'x'。如果用户无法使用密码登录,则会返回'*'。

uid

包含用户的整数用户ID(uid)。

gid

包含用户主组的整数组ID(gid)。

dir

以String形式包含用户主目录的路径。

shell

包含用户的登录shell的路径作为字符串。

以下成员是可选的,并且必须使用特殊标志进行编译:

gecos

包含用户的更长字符串描述,例如全名。一些Unix系统在gecos领域提供结构化信息,但这是依赖于系统的。必须与编译HAVE_STRUCT_PASSWD_PW_GECOS

change

密码更改时间(整数)必须使用编译 HAVE_STRUCT_PASSWD_PW_CHANGE

quota

配额值(整数)必须用。编译 HAVE_STRUCT_PASSWD_PW_QUOTA

age

密码的年龄(整数)必须用。编译 HAVE_STRUCT_PASSWD_PW_AGE

class

用户访问类(字符串)必须使用编译 HAVE_STRUCT_PASSWD_PW_CLASS

comment

评论(字符串)必须与编译 HAVE_STRUCT_PASSWD_PW_COMMENT

expire

帐户到期时间(整数)必须用。编译 HAVE_STRUCT_PASSWD_PW_EXPIRE

Tms

公共类方法

json_create(object) 显示源

通过构造具有v序列化值的新结构对象来反序列化JSON字符串to_json

# File ext/json/lib/json/add/struct.rb, line 10 def self.json_create(object) new(*object['v']) end

new(class_name+) → StructClass 显示源

new(class_name+) {|StructClass| block } → StructClass

new(value, ...) → object

StructClassvalue, ... → object

前两个表单用于创建一个新的Struct子类class_name,其中可以包含每个值的值member_name。这个子类可以像任何其他类一样用于创建结构的实例。

如果class_name省略,则会创建一个匿名结构类。否则,此结构的名称将在类Struct中显示为常量,因此它必须对系统中的所有Structs都是唯一的,并且必须以大写字母开头。给一个常量赋一个结构类也给这个类定义了这个常量的名字。

# Create a structure with a name under Struct Struct.new("Customer", :name, :address) #=> Struct::Customer Struct::Customer.new("Dave", "123 Main") #=> #<struct Struct::Customer name="Dave", address="123 Main"> # Create a structure named by its constant Customer = Struct.new(:name, :address) #=> Customer Customer.new("Dave", "123 Main") #=> #<struct Customer name="Dave", address="123 Main">

如果给出了一个块,它将在上下文中进行评估StructClass,将创建的类作为参数传递:

Customer = Struct.new(:name, :address) do def greeting "Hello #{name}!" end end Customer.new("Dave", "123 Main").greeting #=> "Hello Dave!"

这是定制结构的推荐方法。子类化匿名结构会创建一个永远不会被使用的额外的匿名类。

最后两个窗体创建一个结构子类的新实例。value参数的数量必须小于或等于为结构定义的属性的数量。取消设置参数默认为nil。传递比属性数量更多的参数会引发ArgumentError。

Customer = Struct.new(:name, :address) Customer.new("Dave", "123 Main") #=> #<struct Customer name="Dave", address="123 Main"> Customer["Dave"] #=> #<struct Customer name="Dave", address=nil>

static VALUE rb_struct_s_def(int argc, VALUE *argv, VALUE klass) { VALUE name, rest; long i; VALUE st; st_table *tbl; rb_check_arity(argc, 1, UNLIMITED_ARGUMENTS name = argv[0]; if (SYMBOL_P(name)) { name = Qnil; } else { --argc; ++argv; } rest = rb_ident_hash_new( RBASIC_CLEAR_CLASS(rest tbl = RHASH_TBL(rest for (i=0; i<argc; i++) { VALUE mem = rb_to_symbol(argv[i] if (st_insert(tbl, mem, Qtrue)) { rb_raise(rb_eArgError, "duplicate member: %"PRIsVALUE, mem } } rest = rb_hash_keys(rest st_clear(tbl RBASIC_CLEAR_CLASS(rest OBJ_FREEZE_RAW(rest if (NIL_P(name)) { st = anonymous_struct(klass } else { st = new_struct(name, klass } setup_struct(st, rest if (rb_block_given_p()) { rb_mod_module_eval(0, 0, st } return st; }

公共实例方法

struct == other→true或false显示源代码

Equality-Returns true如果other具有相同的结构子类并具有相同的成员值(根据Object#==)。

Customer = Struct.new(:name, :address, :zip) joe = Customer.new("Joe Smith", "123 Maple, Anytown NC", 12345) joejr = Customer.new("Joe Smith", "123 Maple, Anytown NC", 12345) jane = Customer.new("Jane Doe", "456 Elm, Anytown NC", 12345) joe == joejr #=> true joe == jane #=> false

static VALUE rb_struct_equal(VALUE s, VALUE s2) { if (s == s2) return Qtrue; if (!RB_TYPE_P(s2, T_STRUCT)) return Qfalse; if (rb_obj_class(s) != rb_obj_class(s2)) return Qfalse; if (RSTRUCT_LEN(s) != RSTRUCT_LEN(s2)) { rb_bug("inconsistent struct" /* should never happen */ } return rb_exec_recursive_paired(recursive_equal, s, s2, s2 }

structmember → object 显示源

structindex → object

属性引用 - 返回给定结构的值member或给定的成员index。如果member不存在则引发NameError,如果index超出范围则引发IndexError 。

Customer = Struct.new(:name, :address, :zip) joe = Customer.new("Joe Smith", "123 Maple, Anytown NC", 12345) joe["name"] #=> "Joe Smith" joe[:name] #=> "Joe Smith" joe[0] #=> "Joe Smith"

VALUE rb_struct_aref(VALUE s, VALUE idx) { int i = rb_struct_pos(s, &idx if (i < 0) invalid_struct_pos(s, idx return RSTRUCT_GET(s, i }

structmember = obj → obj 显示源

structindex = obj → obj

属性分配 - 设置给定结构member或给定成员的值index。如果member不存在则引发NameError,如果index超出范围则引发IndexError 。

Customer = Struct.new(:name, :address, :zip) joe = Customer.new("Joe Smith", "123 Maple, Anytown NC", 12345) joe["name"] = "Luke" joe[:zip] = "90210" joe.name #=> "Luke" joe.zip #=> "90210"

VALUE rb_struct_aset(VALUE s, VALUE idx, VALUE val) { int i = rb_struct_pos(s, &idx if (i < 0) invalid_struct_pos(s, idx rb_struct_modify(s RSTRUCT_SET(s, i, val return val; }

as_json(*) 显示源

返回一个散列,它将变成一个JSON对象并表示这个对象。

# File ext/json/lib/json/add/struct.rb, line 16 def as_json(*) klass = self.class.name klass.to_s.empty? and raise JSON::JSONError, "Only named structs are supported!" { JSON.create_id => klass, 'v' => values, } end

dig(key, ...) → object 显示源

key通过dig在每个步骤调用来抽取由对象序列指定的嵌套值,nil如果有任何中间步骤则返回nil

Foo = Struct.new(:a) f = Foo.new(Foo.new{b: [1, 2, 3]})) f.dig(:a, :a, :b, 0) # => 1 f.dig(:b, 0) # => nil f.dig(:a, :a, :b, :c) # TypeError: no implicit conversion of Symbol into Integer

static VALUE rb_struct_dig(int argc, VALUE *argv, VALUE self) { rb_check_arity(argc, 1, UNLIMITED_ARGUMENTS self = rb_struct_lookup(self, *argv if (!--argc) return self; ++argv; return rb_obj_dig(argc, argv, self, Qnil }

each {|obj| block } → struct 显示源

each → enumerator

按顺序产生每个结构成员的值。如果没有给出块,则返回枚举器。

Customer = Struct.new(:name, :address, :zip) joe = Customer.new("Joe Smith", "123 Maple, Anytown NC", 12345) joe.each {|x| puts(x) }

生产:

Joe Smith 123 Maple, Anytown NC 12345

static VALUE rb_struct_each(VALUE s) { long i; RETURN_SIZED_ENUMERATOR(s, 0, 0, struct_enum_size for (i=0; i<RSTRUCT_LEN(s i++) { rb_yield(RSTRUCT_GET(s, i) } return s; }

each_pair {|sym, obj| block } → struct 显示源

each_pair → enumerator

按顺序产生每个结构成员的名称和值。如果没有给出块,则返回枚举器。

Customer = Struct.new(:name, :address, :zip) joe = Customer.new("Joe Smith", "123 Maple, Anytown NC", 12345) joe.each_pair {|name, value| puts("#{name} => #{value}") }

生产:

name => Joe Smith address => 123 Maple, Anytown NC zip => 12345

static VALUE rb_struct_each_pair(VALUE s) { VALUE members; long i; RETURN_SIZED_ENUMERATOR(s, 0, 0, struct_enum_size members = rb_struct_members(s if (rb_block_arity() > 1) { for (i=0; i<RSTRUCT_LEN(s i++) { VALUE key = rb_ary_entry(members, i VALUE value = RSTRUCT_GET(s, i rb_yield_values(2, key, value } } else { for (i=0; i<RSTRUCT_LEN(s i++) { VALUE key = rb_ary_entry(members, i VALUE value = RSTRUCT_GET(s, i rb_yield(rb_assoc_new(key, value) } } return s; }

eql?(other) → true or false 显示源

散列相等 - 如果它们具有相同的结构子类并具有相同的成员值(根据Object#eql?)other,则struct引用相同的散列键。

static VALUE rb_struct_eql(VALUE s, VALUE s2) { if (s == s2) return Qtrue; if (!RB_TYPE_P(s2, T_STRUCT)) return Qfalse; if (rb_obj_class(s) != rb_obj_class(s2)) return Qfalse; if (RSTRUCT_LEN(s) != RSTRUCT_LEN(s2)) { rb_bug("inconsistent struct" /* should never happen */ } return rb_exec_recursive_paired(recursive_eql, s, s2, s2 }

hash → integer 显示源

根据这个结构的内容返回一个散列值。

static VALUE rb_struct_hash(VALUE s) { long i, len; st_index_t h; VALUE n; const VALUE *ptr; h = rb_hash_start(rb_hash(rb_obj_class(s)) ptr = RSTRUCT_CONST_PTR(s len = RSTRUCT_LEN(s for (i = 0; i < len; i++) { n = rb_hash(ptr[i] h = rb_hash_uint(h, NUM2LONG(n) } h = rb_hash_end(h return INT2FIX(h }

to_s → string 显示源

inspect → string

以字符串形式返回此结构的描述。

static VALUE rb_struct_inspect(VALUE s) { return rb_exec_recursive(inspect_struct, s, 0 }

另外别名为:to_s

length → integer 显示源

返回结构成员的数量。

Customer = Struct.new(:name, :address, :zip) joe = Customer.new("Joe Smith", "123 Maple, Anytown NC", 12345) joe.length #=> 3

VALUE rb_struct_size(VALUE s) { return LONG2FIX(RSTRUCT_LEN(s) }

members → array 显示源

以符号数组形式返回结构成员:

Customer = Struct.new(:name, :address, :zip) joe = Customer.new("Joe Smith", "123 Maple, Anytown NC", 12345) joe.members #=> [:name, :address, :zip]

static VALUE rb_struct_members_m(VALUE obj) { return rb_struct_s_members_m(rb_obj_class(obj) }

select {|obj| block } → array 显示源

select → enumerator

将每个成员值从结构体传递到块,并返回一个Array struct,其中包含给定块返回true值(等于Enumerable#select)的成员值。

Lots = Struct.new(:a, :b, :c, :d, :e, :f) l = Lots.new(11, 22, 33, 44, 55, 66) l.select {|v| v.even? } #=> [22, 44, 66]

static VALUE rb_struct_select(int argc, VALUE *argv, VALUE s) { VALUE result; long i; rb_check_arity(argc, 0, 0 RETURN_SIZED_ENUMERATOR(s, 0, 0, struct_enum_size result = rb_ary_new( for (i = 0; i < RSTRUCT_LEN(s i++) { if (RTEST(rb_yield(RSTRUCT_GET(s, i)))) { rb_ary_push(result, RSTRUCT_GET(s, i) } } return result; }

size → integer 显示源

返回结构成员的数量。

Customer = Struct.new(:name, :address, :zip) joe = Customer.new("Joe Smith", "123 Maple, Anytown NC", 12345) joe.length #=> 3

VALUE rb_struct_size(VALUE s) { return LONG2FIX(RSTRUCT_LEN(s) }

to_a → array 显示源

以数组形式返回此结构的值。

Customer = Struct.new(:name, :address, :zip) joe = Customer.new("Joe Smith", "123 Maple, Anytown NC", 12345) joe.to_a[1] #=> "123 Maple, Anytown NC"

static VALUE rb_struct_to_a(VALUE s) { return rb_ary_new4(RSTRUCT_LEN(s), RSTRUCT_CONST_PTR(s) }

to_h → hash 显示源

返回包含结构成员的名称和值的哈希。

Customer = Struct.new(:name, :address, :zip) joe = Customer.new("Joe Smith", "123 Maple, Anytown NC", 12345) joe.to_h[:address] #=> "123 Maple, Anytown NC"

static VALUE rb_struct_to_h(VALUE s) { VALUE h = rb_hash_new( VALUE members = rb_struct_members(s long i; for (i=0; i<RSTRUCT_LEN(s i++) { rb_hash_aset(h, rb_ary_entry(members, i), RSTRUCT_GET(s, i) } return h; }

to_json(*args) 显示源

将具有结构值的类名称(Struct)存储v为JSON字符串。仅支持命名的结构。

# File ext/json/lib/json/add/struct.rb, line 27 def to_json(*args) as_json.to_json(*args) end

to_s()

别名为:检查

values → array 显示源

以数组形式返回此结构的值。

Customer = Struct.new(:name, :address, :zip) joe = Customer.new("Joe Smith", "123 Maple, Anytown NC", 12345) joe.to_a[1] #=> "123 Maple, Anytown NC"

static VALUE rb_struct_to_a(VALUE s) { return rb_ary_new4(RSTRUCT_LEN(s), RSTRUCT_CONST_PTR(s) }

values_at(selector, ...) → array 显示源

将每个结构成员值selector作为数组返回。A selector可以是整数偏移量或偏移量范围(如在Array#values_at中)。

Customer = Struct.new(:name, :address, :zip) joe = Customer.new("Joe Smith", "123 Maple, Anytown NC", 12345) joe.values_at(0, 2) #=> ["Joe Smith", 12345]

static VALUE rb_struct_values_at(int argc, VALUE *argv, VALUE s) { return rb_get_values_at(s, RSTRUCT_LEN(s), argc, argv, struct_entry }