在Noda Time v2中,我们正在转向纳秒分辨率.这意味着我们不能再使用8字节整数来表示我们感兴趣的整个时间范围.这促使我调查Noda Time的(很多)结构的内存使用情况,这反过来又导致了我在CLR的对齐决定中发现一点点奇怪.
首先,我意识到这是一个实现决策,并且默认行为可能随时发生变化.我意识到我可以使用[StructLayout]和修改它[FieldOffset],但我想提出一个解决方案,如果可能的话不需要它.
我的核心方案是我有一个struct包含引用类型字段和另外两个值类型字段,其中这些字段是简单的包装器int.我希望,这将被表示为对64位的CLR(8用于参考和4每个其他)16个字节,但由于某些原因它使用24个字节.顺便说一下,我正在使用数组测量空间 - 我知道布局在不同的情况下可能会有所不同,但这感觉就像一个合理的起点.
这是一个展示问题的示例程序:
using System;
using System.Runtime.InteropServices;
#pragma warning disable 0169
struct Int32Wrapper
{
int x;
}
struct TwoInt32s
{
int x, y;
}
struct TwoInt32Wrappers
{
Int32Wrapper x, y;
}
struct RefAndTwoInt32s
{
string text;
int x, y;
}
struct RefAndTwoInt32Wrappers
{
string text;
Int32Wrapper x, y;
}
class Test
{
static void Main()
{
Console.WriteLine("Environment: CLR {0} …Run Code Online (Sandbox Code Playgroud) 我知道.NET中的结构不支持继承,但不清楚为什么它们以这种方式受限.
什么技术原因阻止结构继承其他结构?
我需要从mongo数据库中获取一个项目,所以我定义了一个像这样的结构
type Page struct {
PageId string `bson:"pageId"`
Meta map[string]interface{} `bson:"meta"`
}
Run Code Online (Sandbox Code Playgroud)
现在我还需要将它编码为JSON,但它将字段编码为大写(我得到PageId而不是pageId)所以我还需要为JSON定义字段标签.我试过这样的东西,但它不起作用:
type Page struct {
PageId string `bson:"pageId",json:"pageId"`
Meta map[string]interface{} `bson:"meta",json:"pageId"`
}
Run Code Online (Sandbox Code Playgroud)
那么如何做到这一点,在结构中定义多个名称标签?
以下问题有多种答案/技巧:
我有几个答案,但需要进一步讨论.
这是我想写的结构:
public struct AttackTraits
{
public AttackTraits(double probability, int damage, float distance)
{
Probability = probability;
Distance = distance;
Damage = damage;
}
private double probability;
public double Probability
{
get
{
return probability;
}
set
{
if (value > 1 || value < 0)
{
throw new ArgumentOutOfRangeException("Probability values must be in the range [0, 1]");
}
probability = value;
}
}
public int Damage { get; set; }
public float Distance { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
这会导致以下编译错误:
在分配所有字段之前,不能使用"this"对象 …
在完成我的C++类之后,在我看来,结构/类几乎完全相同,除了一些细微的差别.
我以前从未用C语言编程; 但我确实知道它有结构.在C中是否可以继承其他结构并设置公共/私有的修饰符?
如果你能在常规C中做到这一点,为什么我们需要C++?是什么让类与结构不同?
如果我有这样的结构:
typedef struct
{
unsigned char c1;
unsigned char c2;
} myStruct;
Run Code Online (Sandbox Code Playgroud)
将此结构初始化为0的最简单方法是什么?以下是否足够?
myStruct _m1 = {0};
Run Code Online (Sandbox Code Playgroud)
或者我需要将每个成员显式初始化为0吗?
myStruct _m2 = {0,0};
Run Code Online (Sandbox Code Playgroud) 无论代码有多糟糕,并且假设对齐等在编译器/平台上不是问题,这种未定义或破坏的行为是什么?
如果我有这样的结构: -
struct data
{
int a, b, c;
};
struct data thing;
Run Code Online (Sandbox Code Playgroud)
它是合法的访问a,b并c作为(&thing.a)[0],(&thing.a)[1]和(&thing.a)[2]?
在每种情况下,在我尝试过的每个编译器和平台上,我尝试过的每个设置都"有效".我只是担心编译器可能没有意识到b和thing [1]是相同的东西,并且'b'的存储可能被放入寄存器中,而东西[1]从内存中读取错误的值(例如).在每种情况下,我都尝试过它做了正确的事情.(我当然意识到这一点并不多见)
这不是我的代码; 它是我必须使用的代码,我对这是坏代码还是破坏代码感兴趣,因为不同影响我更改它的优先级:)
标记C和C++.我最感兴趣的是C++,但如果它不同,我也会感兴趣.
我试图声明一个依赖于另一个结构的结构.我想用来sizeof保证安全/迂腐.
typedef struct _parent
{
float calc ;
char text[255] ;
int used ;
} parent_t ;
Run Code Online (Sandbox Code Playgroud)
现在我想声明一个child_t大小相同的结构parent_t.text.
我怎样才能做到这一点?(下面的伪代码.)
typedef struct _child
{
char flag ;
char text[sizeof(parent_t.text)] ;
int used ;
} child_t ;
Run Code Online (Sandbox Code Playgroud)
我试着用几种不同的方法parent_t和struct _parent,但我的编译器不接受.
作为一个技巧,这似乎工作:
parent_t* dummy ;
typedef struct _child
{
char flag ;
char text[sizeof(dummy->text)] ;
int used ;
} child_t ;
Run Code Online (Sandbox Code Playgroud)
是否可以在child_t不使用的情况下声明dummy?
以前,当我需要存储一些相关变量时,我会创建一个类.
function Item(id, speaker, country) {
this.id = id;
this.speaker = spkr;
this.country = country;
}
var myItems = [
new Item(1, 'john', 'au'),
new Item(2, 'mary', 'us')
];
Run Code Online (Sandbox Code Playgroud)
但我想知道这是不是一个好习惯.还有其他更好的方法来模拟Javascript中的结构吗?
struct ×10
c ×3
.net ×2
c# ×2
c++ ×2
go ×2
class ×1
clr ×1
constructor ×1
inheritance ×1
javascript ×1
json ×1
sizeof ×1