我刚刚写了一个简单的PHP脚本,我有一些非常奇怪的行为.我把它减少到重新创建bug所需的最小值:
<?php
$arr = array("foo",
"bar",
"baz");
foreach ($arr as &$item) { /* do nothing by reference */ }
print_r($arr);
foreach ($arr as $item) { /* do nothing by value */ }
print_r($arr); // $arr has changed....why?
?>
Run Code Online (Sandbox Code Playgroud)
这输出:
Array
(
[0] => foo
[1] => bar
[2] => baz
)
Array
(
[0] => foo
[1] => bar
[2] => bar
)
Run Code Online (Sandbox Code Playgroud)
这是一个错误还是一些应该发生的奇怪行为?
我知道标题听起来很熟悉,因为有很多类似的问题,但我要问问题的不同方面(我知道在堆栈上放置东西并将它们放在堆上之间的区别).
在Java中,我总是可以返回对"本地"对象的引用
public Thing calculateThing() {
Thing thing = new Thing();
// do calculations and modify thing
return thing;
}
Run Code Online (Sandbox Code Playgroud)
在C++中,要做类似的事情,我有2个选项
(1)每当我需要"返回"一个对象时,我都可以使用引用
void calculateThing(Thing& thing) {
// do calculations and modify thing
}
Run Code Online (Sandbox Code Playgroud)
然后像这样使用它
Thing thing;
calculateThing(thing);
Run Code Online (Sandbox Code Playgroud)
(2)或者我可以返回指向动态分配对象的指针
Thing* calculateThing() {
Thing* thing(new Thing());
// do calculations and modify thing
return thing;
}
Run Code Online (Sandbox Code Playgroud)
然后像这样使用它
Thing* thing = calculateThing();
delete thing;
Run Code Online (Sandbox Code Playgroud)
使用第一种方法我不必手动释放内存,但对我而言,它使代码难以阅读.第二种方法的问题是,我必须记住delete thing;,这看起来不太好.我不想返回复制的值,因为它效率低(我认为),所以这里提出问题
我正在学习/试验Rust,在我用这种语言找到的所有优雅中,有一个让我感到困惑并且看起来完全不合适的特点.
在进行方法调用时,Rust会自动取消引用指针.我做了一些测试来确定确切的行为:
struct X { val: i32 }
impl std::ops::Deref for X {
type Target = i32;
fn deref(&self) -> &i32 { &self.val }
}
trait M { fn m(self); }
impl M for i32 { fn m(self) { println!("i32::m()"); } }
impl M for X { fn m(self) { println!("X::m()"); } }
impl M for &X { fn m(self) { println!("&X::m()"); } }
impl M for &&X { fn m(self) { println!("&&X::m()"); } }
impl M for &&&X { …Run Code Online (Sandbox Code Playgroud) 可能重复:
如何在.Net(特别是C#)中深层复制对象?
请看下面的代码(摘自C#书):
public class MyClass
{
public int val;
}
public struct myStruct
{
public int val;
}
public class Program
{
private static void Main(string[] args)
{
MyClass objectA = new MyClass();
MyClass objectB = objectA;
objectA.val = 10;
objectB.val = 20;
myStruct structA = new myStruct();
myStruct structB = structA;
structA.val = 30;
structB.val = 40;
Console.WriteLine("objectA.val = {0}", objectA.val);
Console.WriteLine("objectB.val = {0}", objectB.val);
Console.WriteLine("structA.val = {0}", structA.val);
Console.WriteLine("structB.val = {0}", structB.val);
Console.ReadKey();
}
}
Run Code Online (Sandbox Code Playgroud)
我知道它会产生下面的输出
objectA.val …Run Code Online (Sandbox Code Playgroud) 我收到此错误:
找不到类型或命名空间名称'AutoMapper'(您是否缺少using指令或程序集引用?)
有趣的是,我已经在我的项目中有了这个参考:

这是我的代码:
using System.Collections.Generic;
using DataContract;
using SelectorDAL;
using AutoMapper;
namespace SpecimenSelect
{
public class SpecimenSelect : ISpecimenSelect
{
public SpecimenSelect()
{
SetupMaps();
}
private static void SetupMaps()
{
Mapper.CreateMap<SpecimenDetail, SpecimenDetailContract>();
}
Run Code Online (Sandbox Code Playgroud)
另一个奇怪的事情是我的解决方案中有两个其他项目都使用AutoMapper并引用完全相同的AutoMapper.dll文件.他们都完美无缺.
这是一个屏幕截图:

这是代码(编译好):
using System.Collections.Generic;
using AutoMapper;
using DataContract;
using SelectorDAL;
namespace PatientSelect
{
public class PatientSelect : IPatientSelect
{
public PatientSelect()
{
SetupMaps();
}
private void SetupMaps()
{
Mapper.CreateMap<Patient, PatientContract>();
Mapper.CreateMap<OrderedTest, OrderedTestsContract>();
Mapper.CreateMap<Gender, GenderContract>();
}
Run Code Online (Sandbox Code Playgroud)
两个引用似乎在属性页面上具有相同的数据.
我错过了什么?
我试过了:
AutoMapper.Mapper.CreateMap)还有其他想法吗?
如果我们想从方法中获取值,我们可以使用返回值,如下所示:
public int GetValue();
Run Code Online (Sandbox Code Playgroud)
要么:
public void GetValue(out int x);
Run Code Online (Sandbox Code Playgroud)
我真的不明白它们之间的差异,所以,不知道哪个更好.你能解释一下这个吗?
谢谢.
我已经读过.NET支持返回引用,但C#没有.有特殊原因吗?为什么我不能做这样的事情:
static ref int Max(ref int x, ref int y)
{
if (x > y)
return ref x;
else
return ref y;
}
Run Code Online (Sandbox Code Playgroud) 我们来举个例子吧
a=['help', 'copyright', 'credits', 'license']
b=a
b.append('XYZ')
b
['help', 'copyright', 'credits', 'license', 'XYZ']
a
['help', 'copyright', 'credits', 'license', 'XYZ']
Run Code Online (Sandbox Code Playgroud)
我想在列表'b'中附加值,但列表'a'的值也已更改.
我想我不知道为什么会这样(python通过引用传递列表).
我的问题是"如何通过值传递它,以便附加'b'不会改变'a'中的值?"
以下代码无法编译.
int a = 1, b = 2, c = 3;
int& arr[] = {a,b,c,8};
Run Code Online (Sandbox Code Playgroud)
C++标准对此有何看法?
我知道我可以声明一个包含引用的类,然后创建该类的数组,如下所示.但我真的想知道为什么上面的代码不能编译.
struct cintref
{
cintref(const int & ref) : ref(ref) {}
operator const int &() { return ref; }
private:
const int & ref;
void operator=(const cintref &);
};
int main()
{
int a=1,b=2,c=3;
//typedef const int & cintref;
cintref arr[] = {a,b,c,8};
}
Run Code Online (Sandbox Code Playgroud)
可以使用struct cintref而不是const int &模拟引用数组.