显式声明和隐式声明都是啥时候用?该用哪一个?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了显式声明和隐式声明都是啥时候用?该用哪一个?相关的知识,希望对你有一定的参考价值。

参考技术A   以BASIC为例

  隐式和显式声明
  默认情况下,Visual Basic 编译器强制使用“显式声明”,它要求在使用每个变量前先声明变量。可以去掉此要求并允许“隐式声明”。Visual Basic 提供了一个控制显式声明的开关。如果关闭此开关,则不用声明变量就可以使用变量。

  可以用以下任何方法将显式声明开关设置为打开或关闭:

  在集成开发环境 (IDE) 的“属性”窗口中设置合适的项目属性
  指定 /optionexplicit 命令行编译器选项
  将 Option Explicit 语句包含在代码的开头
  如果使用 Option Explicit 语句,设置将重写项目属性和编译器选项设置,但只针对该语句所在的源代码文件。

  将 Option Explicit 设置为 On 具有强制在编译时(而不是在运行时)进行类型推理的优点。这将提高性能。

  隐式声明
  如果关闭显式声明,则可以隐式声明变量,只需在代码中使用它即可。所有隐式声明的变量都具有 Object 数据类型。但是,如果显式声明所有变量并使用特定的数据类型,则应用程序的效率会更高。这将减少命名冲突错误和拼写错误的发生。它也允许编译器检测潜在的运行时错误,如将 Integer 赋给 Short。

  可以写一个不声明局部变量的函数,如下例所示:

  Function SafeSqrt(Num)
  TempVal = Math.Abs(Num) ' Make sure value is positive for square root.
  Return Math.Sqrt(TempVal)
  End Function
  Visual Basic 自动将 TempVal 创建为一个局部变量,可以像显式声明了该变量一样使用它。虽然这样很方便,但如果拼错了变量名,可能会在代码中导致细微的错误。假设在前面的示例中写了如下函数:

  Function SafeSqrt(Num)
  TempVal = Math.Abs(Num) ' Make sure value is positive for square root.
  Return Math.Sqrt(TemVal)
  End Function
  此代码初看上去与原来的一样。但它拼错了 Sqrt 的参数 TempVal 变量,因此编译器将另外创建一个称为 TemVal 的局部变量,它不会被赋值,并且函数将总是返回零。

  Visual Basic 遇到新名称时,它无法确定您是要隐式声明新变量还是仅仅拼错了现有变量,因此它用该名称创建一个新变量。另一种可能是,编译器可能已经定义了该名称,而代码将在不自觉中使用该定义。

  通过使用显式声明可以避免由拼错变量名引起的问题。

  显式声明
  如果显式声明对前面的示例中包含 SafeSqrt 函数的模块有效,则 Visual Basic 会将 TempVal 和 TemVal 识别为未声明的变量,并对它们都生成错误。因此,应将 TempVal 显式地声明如下:

  Function SafeSqrt(Num As Single) As Single
  Dim TempVal As Single = Math.Abs(Num)
  Return Math.Sqrt(TemVal)
  End Function
  通过这个修订过的代码,您会立即了解问题所在,因为 Visual Basic 会针对拼错的 TemVal 显示一条错误信息。鉴于显式声明有助于捕捉这些类型的错误,建议在所有代码中使用显式声明。

  注意 Option Explicit 语句基于每个文件进行操作。该语句必须位于每个想用来控制显式变量声明的执行的源代码文件的开头。

Scala和隐式导入?

首先,我必须告诉我,我不熟悉Scala,最近我读了一些代码,我不明白它是如何工作的。

此示例代码使用的是Future,通常它们都需要scala.concurrent.ExecutionContext.Implicits.global,但在项目代码中没有声明。当我尝试在我的IntelliJ项目中使用Future时,它抱怨我必须在某处声明一个ExecutionContext ...

同样的import scala.collection.JavaConverters._。示例代码一直使用asScala而不导入转换器...

有没有办法在Scala中配置这样的项目(或者可能是IntelliJ中的技巧)...

答案

我认为这与IntelliJ无关。

一种可能的解释是,您引用的代码在某些全局导入的范围中声明了这些含义,如package object。在这种情况下,包的任何成员都将看到在此对象中声明的含义。

另一答案

在Intellij中,您可以使用快捷方式Ctrl+Shift+Alt++(隐式提示)来查找代码中使用的含义(以及缺少的含义)(它们以浅灰色显示,您可以在它们上面使用CTRL+click)。见:https://www.jetbrains.com/help/idea/edit-scala-code.html#scala_hints

因此,如果您继续打开IntelliJ中未理解的代码并激活隐式提示,您将能够看到隐含定义的位置。

对于您的情况:尝试在您需要隐含的import scala.concurrent.ExecutionContext.Implicits.global的文件中使用ExecutionContext

有没有办法在Scala中配置这样的项目(或者可能是IntelliJ中的技巧)...

不,您必须在范围内的某处定义implicits或导入它们。 (伴随对象也适用)。阅读本文以获得更详细的解释:https://docs.scala-lang.org/tour/implicit-parameters.html

以上是关于显式声明和隐式声明都是啥时候用?该用哪一个?的主要内容,如果未能解决你的问题,请参考以下文章

vb.net2010中的隐式声明和显示声明分别是啥

C#显式声明隐式声明是怎么定义的

android--显式跳转和隐式跳转

c++ 隐式声明是啥意思

(转载)Android理解:显式和隐式Intent

ReSharper 和隐式类型变量