DELPHI盒子
!实时搜索: 盒子论坛 | 注册用户 | 修改信息 | 退出
检举帖 | 全文检索 | 关闭广告 | 捐赠
技术论坛
 用户名
 密  码
自动登陆(30天有效)
忘了密码
≡技术区≡
DELPHI技术
移动应用开发
Web应用开发
数据库专区
报表专区
网络通讯
开源项目
论坛精华贴
≡发布区≡
发布代码
发布控件
文档资料
经典工具
≡事务区≡
网站意见
盒子之家
招聘应聘
信息交换
论坛信息
最新加入: ajkwhduaduiahdui
今日帖子: 22
在线用户: 2
导航: 论坛 -> DELPHI技术 斑竹:liumazi,sephil  
作者:
男 msdtx (yong) ★☆☆☆☆ -
普通会员
2024/1/20 19:53:46
标题:
Lazarus 警告 out 输出参数没有初始化 浏览:669
加入我的收藏
楼主: 按照它的几行简陋说明 out 修饰的参数是不考虑初始化的,同样的要求也适用于 C#。但是编译时总带着警告参数没有初始化!对于一个典型的TList,到底要怎样传递才符合它的口味?
----------------------------------------------
-
作者:
男 keymark (嬲) ▲▲▲△△ -
普通会员
2024/1/20 22:28:56
1楼: 代码一行没有隔这说小品呢?
----------------------------------------------
[alias]  co = clone --recurse-submodules  up = submodule update --init --recursiveupd = pullinfo = statusrest = reset --hard懒鬼提速https://www.cctry.com/>http://qalculate.github.io/downloads.htmlhttps://www.cctry.com/
作者:
男 msdtx (yong) ★☆☆☆☆ -
普通会员
2024/1/21 0:00:17
2楼: 最基础的
procedure OutPutList(out idxTest:TList);
begin
  idxTest.Clear; //这里报没有初始化
  idxTest.Add(2);
end;
你只要用过out修饰符,就不至于没遇到这个警告;
----------------------------------------------
-
作者:
男 bighawk (Hawk) ★☆☆☆☆ -
盒子活跃会员
2024/1/21 9:49:39
3楼: 按照 pascal 的语法逻辑,这个参数应该是函数内赋值的,这个警告没问题。
----------------------------------------------
-
作者:
男 kentty (kentty) ★☆☆☆☆ -
普通会员
2024/1/21 18:16:57
4楼: out修饰符表示在函数内部初始化,
但你显然没有初始化啊
并不是编译器替你初始化
编译器没毛病
----------------------------------------------
-
作者:
男 keymark (嬲) ▲▲▲△△ -
普通会员
2024/1/21 19:17:14
5楼: https://wiki.freepascal.org/Reserved_words  似乎没有wiki

https://blog.csdn.net/liujiayu2/article/details/70172728
````
//Out关键字说明了方法参数的输出方式, 一般的函数只能有一个返回值,   
//使用Out可以在一个函数中返回多个结果.  
//Out和var不同, Out是以返回值的形式进行参数返回, 而var是直接输入一个参数的地址.  
procedure X(out i: Integer; out s: string);  
begin  
 i := i * 2;  
 s := s + 'abc';  
end;  
procedure TForm1.Button1Click(Sender: TObject);  
var  
 i: Integer;  
 s: string;  
begin  
 i := 20;  
 s := 'xxx';  
 X(i,s);  
end;  

````
----------------------------------------------
[alias]  co = clone --recurse-submodules  up = submodule update --init --recursiveupd = pullinfo = statusrest = reset --hard懒鬼提速https://www.cctry.com/>http://qalculate.github.io/downloads.htmlhttps://www.cctry.com/
作者:
男 roadrunner (roadrunner) ★☆☆☆☆ -
盒子活跃会员
2024/1/22 11:07:04
6楼: @msdtx 在你的代码里,函数开始执行时idxTest的值就是一个野指针
你对一个野指针调用了一个clear方法,可能会产生灾难性后果,抛异常算好的,甚至可能会不抛异常直接破坏其他数据。

理论上你不一定要对idxTest初始化,但编译器为了防止码农犯和你一样的错误特意给出了提示。
----------------------------------------------
-
作者:
男 msdtx (yong) ★☆☆☆☆ -
普通会员
2024/1/22 12:09:52
7楼: @roadrunner Java里被喷死的到处检查空对象在Kotlin改成要求非空。D7里面也是这个思路,对out参数你就提前保证它非空;只有var这种不管不问的地方才自己去检查所有。现在FreePascal里这样该输出的用const,叫不合常理好不好,现在为了关闭警告只能用var,但是var修饰你不检查它反不做任何警告。这不TM搞乱吗?
----------------------------------------------
-
作者:
男 kentty (kentty) ★☆☆☆☆ -
普通会员
2024/1/22 12:52:45
8楼: out修饰符就是告诉调用方,你不用管是不是野指针,我来搞定全部
所以函数内部一定要对传入的指针进行检查处理
否则如果调用方直接传入野指针的idxTest,必然会出错

根据原帖里面的函数实现,已经默认idxTest已经初始化,其实用不到out,用const都可以,因为并没有改变idxTest的指针地址,只是改变了指针地址指向的内容
用var的话,意味着可以改变idxTest的指针地址,还需要主动释放idxTest之前的指针

总体来说,具体采用什么实现,取决于上下文的需求
----------------------------------------------
-
作者:
男 bamboocaep (bamboocaep) ★☆☆☆☆ -
普通会员
2024/1/22 13:00:12
9楼: 同意楼上@kentty的说法
你既然都申明out idxTest:TList了,那这个idxTest就应该在函数内部创建好给外部用,哪怕是赋值nil也行,总之不能是未定义
----------------------------------------------
-
作者:
男 roadrunner (roadrunner) ★☆☆☆☆ -
盒子活跃会员
2024/1/22 13:01:21
9楼: out 修饰符代表着根本就不会传入参数,对于管理对象(字符串,动态数组,接口)会有空初始值,对于对象参数初始值就是野指针
----------------------------------------------
-
作者:
男 msdtx (yong) ★☆☆☆☆ -
普通会员
2024/1/22 13:26:17
10楼: Delphi,C#,Kotlin 都认可的东西,它 FreePascal 一个继任者有什么抱怨的?就是C++它能用引用也绝不用指针。该输出的情况其它类型都是out修饰,到Object就成const了?而且这个警告生成的二进制代码还是完全正确的,这就更想骂人了。
----------------------------------------------
-
作者:
男 pcplayer (pcplayer) ★☆☆☆☆ -
普通会员
2024/1/22 16:08:31
11楼: procedure OutPutList(out idxTest:TList);
begin
  idxTest.Clear; //这里报没有初始化
  idxTest.Add(2);
end;

这个 procedure 我们先不看那个 out 来讨论一下。这里也可以是 const 也可以是 var。

不管是哪种,函数(或者方法)的参数,就两种:输入/输出。

输入的这里就不讨论了。因为这里是 out,输出。

一个函数,要输出一些东西。比如一个整数 1234,比如一个字符串 'abcd',比如一个对象的实例.....

对于调用这个函数的地方,就是获得这个输出,是输入。它如何获得这个函数的输出?

所有的输出,最终都是一堆东西,都是占用一个地址空间的一堆东西,不管它是整数,还是字符串,还是对象 Object;

想要获得这个输出的地方(调用这个函数的地方),

A. 要么,自己端一个盆(自己分配空间),把盆子递给这个函数,这个函数把那些东西装盆里;

B. 要么伸手,等那个函数制造好一个盆,把东西装进盆里面,然后把这个盆的把手递到你的手上。

不管用哪种类型,都是这样。

如果是 var,就等于你自己先做一个盆子,把这个盆子的把手递给函数,函数往盆里装东西。

如果是 out,那就是函数连盆子都给你做好,东西也装好,然后把盆子的把手递到你手上。

不知道我这样理解,对不对?

如果是这样理解,那么,out 参数,就必须在函数内部先【初始化】好,意思就是函数内部对这个盆子,该分配内存空间就分配内存空间,该把盆子擦干净就先擦干净。然后把东西装好,把盆子递给(输出给) 外面调用函数的人。
----------------------------------------------
-
作者:
男 itpc1 (itpc1) ▲▲▲▲△ -
普通会员
2024/1/23 0:02:42
12楼: Lazarus实在是太难用了!建议抛弃它,继续用Delphi!
----------------------------------------------
-
作者:
男 bluespark (Spark) ★☆☆☆☆ -
普通会员
2024/1/29 11:04:11
13楼: out参数这功能在C#里就有。不会是学C#的吧。
C#7.0建议用元组,现在建议用值元组返回多个值。
----------------------------------------------
-
信息
登陆以后才能回复
Copyright © 2CCC.Com 盒子论坛 v3.0.1 版权所有 页面执行638.6719毫秒 RSS