每隔几年都要来学一遍,每次都是入门到放弃。直接上代码,懒得解释。
//常规脑回路,写的代码,抱歉了,bug 成堆
$list=array();
for($i=0;$i<10;$i++){
$obj=array();
$list[]=$obj; //后面会有 break 、return 等复杂逻辑,因此此处进行赋值代码量最少
$obj["val"]=$i;
//...一大堆复杂逻辑
}
//list= [{},{},{},......,{}]
数组对象这么重要的东西,默认进行赋值操作竟然是值拷贝。每赋值一次,就整个数组复制一遍。不能说这种方式不妥吧,就是感觉不那么好,说不上来的那种不好!
数组对象赋值采用引用的方式赋值,场景绝对比值拷贝多的多。需要做为全新的一个数组对象来对待的场景,完全可以显式的进行新数组的创建操作。直接就省去了很多麻烦。( PHP 也是老人家了,发了这么多版,随便出个 Array2 搞点完全不同的特性来糊弄我一下也行啊)
//修改代码,显式的进行引用。依旧是常规脑回路,写的代码,抱歉了,bug 还是成堆
$list=array();
for($i=0;$i<10;$i++){
$obj=array();
$list[]=&$obj; //后面会有 break 、return 等复杂逻辑,因此此处进行赋值代码量最少
$obj["val"]=$i;
//...一大堆复杂逻辑
}
//list= [{val:9},{val:9},......,{val:9}]
然后就有了,看似很屌,其实并没有多大卵用的:引用。有意思的是,它是按名字来引用,这个很关键,也很鸡肋。(在函数参数里面似乎有点儿卵用,就算没有引用传递这种东西,引用参数完全可以用别的带有引用性质的东西来代替)
//好了,这回正常了。不过,我的脑回路已经不正常了,劝退中
$list=array();
for($i=0;$i<10;$i++){
unset($obj); //强加的负担,迟早要翻车,漏了就反复调试来定位吧,一次写出的代码能用就怪了
//这种形式的引用方式,不要也罢:赋值一次,所有变量乱窜
$obj=array(); //如果你不是值拷贝,用得着引用?
$list[]=&$obj; //后面会有 break 、return 等复杂逻辑,因此此处进行赋值代码量最少
$obj["val"]=$i;
//...一大堆复杂逻辑
}
//list= [{val:0},{val:1},......,{val:9}]
1
t6attack 2021-12-18 06:20:00 +08:00 2
每门语言的特性不一样,好好的 php 非得按 java 的思路写。
值传递很好,只有数组这一种数据结构很好。千万别按楼主的思路改。也不需要什么 Array2 。 php 没有在不同版本瞎改,向前兼容做的很好,为 php 开发组点个赞。 |
2
zjsxwc 2021-12-18 07:28:24 +08:00 via Android
PHP 的 for 中使用引用一直是潜在 bug 的源头。
|
3
vanton 2021-12-18 08:46:07 +08:00
为啥要在 for 里面引用?
你这思路有点奇怪。 每种语言有存在的意义 ,有自己的风格,硬要都按照 java 的思路去写不是找麻烦么。 |
4
zjsxwc 2021-12-18 09:01:37 +08:00
其实楼主用面向对象的方式写就没有问题了:
https://gist.github.com/zjsxwc/25e7388b777ba56b614fe7f3e9d2b126 |
5
xiangyuecn OP @zjsxwc #2 #4 不是 for 的问题,是 Array 的问题。自己定义的对象,默认赋值就是引用,不存在隐式的复制,自然就不需要自己显式的引用赋值。Array 这个玩意败笔就在默认赋值一下就拷贝一遍,这就注定了逃不过用到&,最终结果就是不常用的引用功能,&要被滥用。
所以我提出一个 Array2 ,理想状态下,默认赋值就是引用,我如果要复制,完全可以自己调用一个函数复制出一个新数组。对于解析器底层实现一个这玩意,我猜测应该也不复杂,比如给 Array 加一个标记,遇到这种特殊的 Array 类型的对象,解析器发现有标记,就跳过复制阶段,直接引用这个,就和对象一样对待应该就 OK 了。 |
6
xiangyuecn OP |
7
xiangyuecn OP @vanton #3 上面标错楼层了
|
8
msg7086 2021-12-18 12:45:38 +08:00 via Android
第二段起手 数组对象 是什么勾八玩意儿?
数组特么的就不是对象。张口闭口整篇文章就在谈一个不存在的东西我也是服了。 数组就是数组。对象才是对象。搞不清楚数组是什么东西可以学,不知道数组和对象是什么关系可以问(答案是没鸟关系)。你要想搞个 array2 对象欢迎自己写一个。在这里叫破喉咙都没人把你当回事。 还谈跨语言写结构。不同语言结构差远了。给你个 haskell 你不得喷这玩意怎么连循环都没有了。PHP 本来就是一个以值传递为主的语言,就算是对象变量也依然是传值的,只不过这个值是对象指针所以写起来会有传引用的效果。你要是起手就想把别的语言根基给整个掀了,我劝你还是回去写 Jaba 吧。 这段逻辑,放在 Python 里是会用 list comprehension 写,放在 Ruby 里会用 block chain 写,放在 Jaba 里可以用 stream lambda 写,放在 PHP 里也只需要把追加数组项那行放在最后就行了。 |
9
msg7086 2021-12-18 12:47:34 +08:00 via Android
> 后面会有 break 、return 等复杂逻辑,因此此处进行赋值代码量最少
复杂逻辑不放进函数里?不封装进对象里? peer review 不会被同事骂死吗? |
10
xiangyuecn OP @msg7086 #9 同事已经拍桌子了,下一步应该要拿刀了😂
“PHP 中的 array 实际上是一个有序映射。映射是一种把 values 关联到 keys 的类型。此类型针对多种不同用途进行了优化; 它可以被视为数组、列表(向量)、哈希表(映射的实现)、字典、集合、堆栈、队列等等。 由于 array 的值可以是其它 array 所以树形结构和多维 array 也是允许的。” 至少在很多地方,它讲的这一套东西叫法,更偏向对象😂 新手:php 没有对象,只有数组(字典也叫数组)😂 ,等学到 class 了才有会发对象😂 |
11
IvanLi127 2021-12-18 13:47:48 +08:00
楼主你使用冒号的方式好奇特……
|
12
weirdo 2021-12-18 15:56:21 +08:00
哈哈哈 ,本来打了一大堆字,最后还是想了想,就说四个字,尊重祝福~
|
13
landers2015 2021-12-18 16:09:45 +08:00
看了下楼主代码,一致同意、确定、一定是语言的问题
|
14
seakingii 2021-12-18 18:28:13 +08:00
你竟敢说 PHP 语言不行?不想活了?
|
15
msg7086 2021-12-18 18:57:33 +08:00 via Android 1
@xiangyuecn 我是从 PHP4 开始写起来的,那时候 PHP 对对象和类的支持还非常简陋原始,PHP 基本是一个面向过程语言(可以看作和 C 非常类似但大幅简化的语言),对象是一个非常小众,很少有人用到的 feature 。大概一直到 2007 年前后我才看到越来越多的项目开始用类结构来构建项目。你想想,像是 Zend framework 这种项目都是 2005 年才开始搞的。但是那时候主流的开发依然是面向过程。2009 年我在一家公司做架构设计,老大还跟我说不要把面向对象结构设计得太复杂,否则老员工玩不明白,于是只好自己写个 MVC 框架,只用了一点点面向对象设计,controller 依然做成了面向过程结构,满足老员工的复古风需求。
PHP4 里的类结构连可见性控制都没有(即没有 private public 之分),没有接口 interface ,也没有引用传递。一直到后来 PHP5 里才加入这些新功能。只不过像是数组这种超大规模使用的特性,不可能说改就改的,这么多年下来的项目,兼容性不可能说砍就砍,毕竟有太多的地方依赖数组传值。 |
16
xiangyuecn OP @msg7086 👍
|
17
Wenco 2021-12-18 22:05:53 +08:00
后面‘$‘, ’->‘ 确实是个槽点,但也没办法,就跟语言定的关键字一样
> 至少在很多地方,它讲的这一套东西叫法,更偏向对象😂 更像数组和 hashmap 的结合体吧 你强行把数组当对象用,然后还怪别人不支持,哪个语言都不支持吧。。。 |
18
qeqv 2021-12-18 22:47:29 +08:00
PHP 的数组就是一种数据结构,见过一些老代码把数组当对象用的,弄了一个超大的数组,然后直接 return 或者给函数传参,导致内存占用疯涨。。。。
另外学语言得搞清楚变量作用域,PHP 的变量只有全局作用域和函数作用域 |
19
loginv2 2021-12-19 09:52:09 +08:00
感觉写$太难受了 所以直接 ahk 伺候了,三击 4 键输入$
$4:: if pressesCount > 0 ; > 0 说明 SetTimer 已经启动了,按键次数递增 { pressesCount += 1 return } ;否则,这是新一系列按键的首次按键。将计数设重置为 1 ,并启动定时器: pressesCount = 1 SetTimer, WaitKey, 400 ;在 400 毫秒内等待更多的按键。 return WaitKey: SetTimer, WaitKey, off if pressesCount = 1 ;该键已按过一次。 { Gosub singleClick } else if pressesCount = 2 ;该键已按过两次。 { Gosub doubleClick } else if pressesCount = 3 { Gosub trebleClick } ;不论上面哪个动作被触发,将计数复位以备下一系列的按键: pressesCount = 0 return singleClick: send 4 return doubleClick: send 44 return trebleClick: send $ return |
20
charlie21 2021-12-19 12:03:59 +08:00
你不配用 PHP
|
21
ivanfjz 2021-12-19 13:25:05 +08:00
你就狗屁不是~~
|
22
limingxinleo 2021-12-20 09:37:17 +08:00
只看了标题,内容我都没看,我就已经得出结论了,
这世界上没有适合你的语言!!! |
23
wowbaby 2021-12-20 09:58:10 +08:00
我从没碰到过类似的问题,我怎么感觉代码执行没有问题啊,是你自己的问题吧?
$list=array(); for($i=0;$i<10;$i++){ $obj=array(); $list[]=$obj $obj["val"]=$i; } 为什么要这么写,又不是对象,能这么写,我头一次看到这样的? 应该是 $obj=array(); $obj["val"]=$i; $list[]=$obj; 这样的顺序吧 $list=array(); for($i=0;$i<10;$i++){ $obj=array(); // 这里已经重置了 $list[]=&$obj; $obj["val"]=$i; } //list= [{val:9},{val:9},......,{val:9}] 这段代码结果也没错啊, |
24
elevioux 2021-12-20 10:25:38 +08:00
list[]=obj ,为什么要先赋值到 list 先呢?
obj 确定以后再赋值不就好了吗?也不用 unset ,引用啥的。 也可以 list[i][val]=1 来操作 obj 。 可能其他语言会有不同习惯,我一直写 php 都没留意。 |
25
sanggao 2021-12-20 10:57:40 +08:00
php 这么亲民友好的语言,你都玩不明白,的确 狗屁不是
|
26
Wenco 2021-12-20 13:03:58 +08:00
@elevioux
> //后面会有 break 、return 等复杂逻辑,因此此处进行赋值代码量最少 因为这个吧,他无法做到在最后一行将 obj 塞入 list ,又不想在每个跳出的地方重复写$list[] = $obj ,更不想优化自己的代码,所以只能吐槽 PHP 了 |
27
JaguarJack 2021-12-20 16:02:05 +08:00
不应该直接
```php $list[] = array('val' => $i); ``` 一行就完事了。看了半天才缓过来 |