GVKun编程网logo

为什么在Swift中初始化变量的行上出现“初始化前使用变量”错误?

27

在这篇文章中,我们将带领您了解为什么在Swift中初始化变量的行上出现“初始化前使用变量”错误?的全貌,同时,我们还将为您介绍有关c–在循环中初始化变量、c–如何使用未初始化的数据有意初始化变量,以便

在这篇文章中,我们将带领您了解为什么在Swift中初始化变量的行上出现“初始化前使用变量”错误?的全貌,同时,我们还将为您介绍有关c – 在循环中初始化变量、c – 如何使用未初始化的数据有意初始化变量,以便valgrind将变量视为未初始化?、c# – 使用null转换为变量的数据类型初始化变量、final变量要么定义时初始化,要么在代码块中初始化的知识,以帮助您更好地理解这个主题。

本文目录一览:

为什么在Swift中初始化变量的行上出现“初始化前使用变量”错误?

为什么在Swift中初始化变量的行上出现“初始化前使用变量”错误?

我正在努力理解为什么我在使用Swift的iOS项目中遇到此编译器错误。如果我创建以下类:

class InitTest {    let a: Int    let b: Int    let c: Int    init () {        self.a = 3        self.b = 4        self.c = self.runCalculation()    }    func runCalculation () -> Int {        return self.a * self.b    }}

我在self.c = self.runCalculation()“初始化前使用了变量’self.c’” 这一行上收到编译器错误。

起初我以为这是因为编译器无法验证该runCalculation()方法是否无法访问self.c,但是后来我尝试将init方法混入一点:

init () {    self.a = 3    self.c = self.runCalculation()    self.b = 4}

这次的错误是“在初始化之前使用了变量’self.b’”(在同一self.runCalculation()行上)。这表明编译器
能够检查其性能的方法访问,所以据我可以看到应该有最初的情况下,没有问题的。

当然,这是一个简单的示例,我可以轻松地进行重构以避免调用计算方法,但是在实际项目中,可能会有多个计算,每个计算都可能涉及到很多。我希望能够分离出保持可读性的逻辑。

幸运的是,有一个简单的解决方法:

init () {    self.a = 3    self.b = 4    self.c = 0    self.c = self.runCalculation()}

(或使用属性初始化程序let c = 0),但我想了解为什么编译器在第一个示例中有问题。我是否缺少某些东西,还是不必要的限制?

答案1

小编典典

由于两阶段初始化,Swift具有此行为。从Apple的Swift书中:

Swift中的类初始化是一个分为两个阶段的过程。在第一阶段,每个存储的属性都由引入它的类分配一个初始值。一旦确定了每个存储属性的初始状态,便开始第二阶段,并且在考虑将新实例准备使用之前,每个类都有机会自定义其存储属性。

在第一阶段结束之前,类需要某种默认值。定制值是第二阶段的一部分。

Objective-C没有这种行为,因为它总是可以0为基元和nil对象提供默认值,但是在Swift中,没有机制可以提供此类默认值。

c – 在循环中初始化变量

c – 在循环中初始化变量

我试图弄清楚在初始化某些变量时最佳做法是什么……
我的代码目前看起来像这样:
int nHexCount = 0;
int prevstate = sc.state;

bool bOnlySpaces = true;
bool bIsValidLabel = true;
bool bIsHotstring = false;
bool bIsValidName = true;
bool bIsValidExpStart = false;                         

bool fInExpression = false;
bool fInStringBlock = (sc.state == SCE_AHKL_STRINGOPTS || sc.state == SCE_AHKL_STRINGBLOCK);

for (; sc.More(); sc.Forward()) {

    if (sc.atLinestart) {
        if (!fInStringBlock && sc.state != SCE_AHKL_COMMENTBLOCK)
            sc.SetState(SCE_AHKL_DEFAULT);

        // Reset Status
        prevstate = sc.state;

        bOnlySpaces = true;
        bIsValidLabel = true;
        bIsHotstring = false;
        bIsValidName = true;
        bIsValidExpStart = false;

        fInExpression = false;
    }

...

因此,每当我的程序在我正在编辑的编辑组件中找到一个新行时,您可以看到大多数这些变量都被重置…

问题是:

是否更好的编程实践声明并初始化for循环中的所有变量,或者我应该像现在这样离开它?

解决方法

您应该尽可能地减少变量的范围.这将提高代码的可维护性,并减少错误的可能性.
// bad
int i,j,k;
k = 0;
for (i = 0; i < X,++i)
{
  j = foo(i);
  k += j;
} 

bar(k);

……对……

// better
int k=0; // needs scope outside loop
for (int i = 0; i < X,++i)
{
  int j = foo(i);
  k += j;
} 

bar(k);

c – 如何使用未初始化的数据有意初始化变量,以便valgrind将变量视为未初始化?

c – 如何使用未初始化的数据有意初始化变量,以便valgrind将变量视为未初始化?

我的代码中有一个垃圾数据缓冲区,我将其传递给写入它的函数.我不需要这个垃圾缓冲区的数据.由于我需要在多个地方使用这样的垃圾数据缓冲区,但从不从它们读取,我到处使用相同的垃圾缓冲区.

当一些虚假代码从垃圾数据缓冲区中读取时,这将是致命的,或者,例如,当我使用垃圾数据缓冲区时,我应该使用适当的专用缓冲区.

理想情况下,我想让伪代码快速崩溃,因此我在调用写入函数后对数据进行加扰,因此没有人可以使用(并依赖)垃圾数据.

现在我有了一个想法,我可以将未初始化的数据复制到垃圾数据而不是加扰它,因此valgrind可以从垃圾缓冲区中找到所有读取.

我当前的解决方案是new []一些字节,并将未初始化的内容复制到垃圾缓冲区,然后删除[]未初始化的数据.由于未初始化的数据在大多数情况下是0(不幸的是),因此我将其与模式进行异或.对于这么简单的事情,这一切似乎都很复杂.

有没有人想出更好的解决方案?

解决方法

Valgrind(和memcheck)有一个 C API!

你可以这样做:

#include <memcheck.h>

// ....

VALGRIND_MAKE_MEM_UNDEFINED(trash_buffer,trash_length);

如果您希望valgrind将数据视为不可访问而不仅仅是单元化,您还可以使用VALGRIND_MAKE_MEM_NOACCESS.

在valgrind外部运行时,这将只有很少的运行时开销.即使不在valgrind中运行,你复制内容的方法也可能很昂贵.

c# – 使用null转换为变量的数据类型初始化变量

c# – 使用null转换为变量的数据类型初始化变量

我遇到了一些像这样的代码:

List<string> list = (List<string>)null;

有没有理由程序员不只是初始化:

List<string> list = null;

这两者有区别吗?

这是从另一种编程语言迁移的习惯吗?也许C,C或Java?

解决方法

Is there a difference between the two?

没有没有区别.

在ILSpy中,此行列表< string> list =(List< string>)null;更改为List< string> list = null;

Is this a habit that migrated from another programming language?

不能说.可能是,早些时候有一些不同于null的东西然后它被改为null.

List<string> list = (List<string>) Session["List"];

final变量要么定义时初始化,要么在代码块中初始化

final变量要么定义时初始化,要么在代码块中初始化

以上基于jdk1.8。final变量如果是静态的,要么定义时初始化,要么在静态代码块中初始化。final变量如果不是静态的,要么定义时初始化,要么在非静态代码块中初始化。

 静态变量定义时初始化:

静态变量在静态代码块中初始化 :

 

import java.util.Calendar;
  • import java.util.Date;
  • import java.util.TimeZone;
  • /**
  • * Title:
  • *
  • * @Author
  • * @CreateTime 2019/6/5 11:16
  • */
  • public class Person2 {
  • private Date birthDate = new Date();
  • // private final Date BOOM_EXP = new Date();//正确
  • private final Date BOOM_EXP;//需要在非静态代码块中初始化
  • //
  • 关于为什么在Swift中初始化变量的行上出现“初始化前使用变量”错误?的介绍已经告一段落,感谢您的耐心阅读,如果想了解更多关于c – 在循环中初始化变量、c – 如何使用未初始化的数据有意初始化变量,以便valgrind将变量视为未初始化?、c# – 使用null转换为变量的数据类型初始化变量、final变量要么定义时初始化,要么在代码块中初始化的相关信息,请在本站寻找。

    本文标签:

    上一篇SwiftUI:如何在单击按钮时显示视图?(swiftui点击按钮跳转)

    下一篇为什么在Java / Spring上使用Scala / Lift?(为啥使用spring)