当我在Kotlin中使用Elvis操作时,我可以添加返回值吗?

时间:2017-09-20 03:03:09

标签: kotlin

我在http://mings.in/2017/03/12/Kotlin-Null-Safety.html

读过Elvis Operator

代码A和代码C都没问题,但是代码B是错误的(“类型不匹配:推断类型是Int但单位是预期的”),为什么?

代码A

override fun onCreate(savedInstanceState: Bundle?) {
      super.onCreate(savedInstanceState)
      setContentView(R.layout.activity_main)  

      val b: String?  = "hello"
      val l = b?.length ?: -1
 }

代码B

   override fun onCreate(savedInstanceState: Bundle?) {
      super.onCreate(savedInstanceState)
      setContentView(R.layout.activity_main)

      val b: String?  = "hello"
      val l = b?.length ?: return -1

    }

代码C

 fun getLength(b: String?): Int {
        val l = b?.length ?: return -1       
        return l
    }
BTW,BakaWaii告诉我“代码A没问题,因为-1是表示值的表达式,因此它可以分配给l。但是在代码B中,返回-1是从函数返回的表达式。 “

我无法理解“在代码B中,返回-1是一个从函数返回的表达式”。我认为“返回-1”将返回-1,为什么应用程序出现“类型不匹配:推断类型是Int但单位是预期的”?

以及更多:

代码C就像代码B一样,我不知道为什么它可以!!!!

2 个答案:

答案 0 :(得分:3)

来自Kotlin's doc

  

如果?:左侧的表达式不为null,则elvis运算符返回它,否则返回右侧的表达式。请注意,由于throwreturn是Kotlin中的表达式,因此它们也可以在elvis运算符的右侧使用。

also

  

return。默认情况下,从最近的封闭函数或匿名函数返回。

所以,答案是肯定的,只要封闭函数的返回类型与返回值匹配,例如:

fun getLength(b: String?): Int {
    val l = b?.length ?: return -1    //return an `Int`
    //if return -1, the code below will not execute
    return l
}

请注意,代码A和代码B在控制流程方面有所不同。如果您在左侧值为null时尝试分配备用/默认值,则代码A将是最佳方法。

答案 1 :(得分:2)

CREATE PROCEDURE [dbo].[dynamicPivot] (@tablename VARCHAR(250), @pivotColumn VARCHAR(250), @groupBy VARCHAR(8000), @aggregateColumns VARCHAR(250), @aggregation VARCHAR(250), @execute INT = 0 ) AS BEGIN DECLARE @sql VARCHAR(8000), @pivotcols VARCHAR(8000)= ''; DECLARE @result TABLE(result VARCHAR(8000)); SET @sql = ' declare @pivotcols varchar(8000) = ''''; with cte as ( select distinct '+@pivotColumn+', ''[''+cast('+@pivotColumn+' as varchar(250))+'']'' col from '+@tablename+') select @pivotcols = @pivotcols + col + '','' from cte order by '+@pivotColumn+'; set @pivotcols = left(@pivotcols, len(@pivotcols)-1); select @pivotcols result'; INSERT INTO @result EXEC (@sql); SELECT @pivotcols = result FROM @result; SET @sql = ' SELECT * FROM ( SELECT '+@groupBy+CASE @groupBy WHEN '' THEN '' ELSE ', ' END+@pivotColumn+', '+@aggregateColumns+' FROM '+@tablename+' ) AS s PIVOT ( '+@aggregation+' FOR '+@pivotColumn+' IN ('+@pivotcols+') )AS p;'; IF @execute = 0 PRINT(@sql); ELSE EXEC (@sql); END; GO Code A之间的差异,第一个设置Code B到您的变量(现在是-1),第二个设置l作为结果功能工作。并且-1错误消息表明该函数不应返回任何值(或返回Type mismatch),但您尝试返回int - 因此它不是Elvis运算符语法错误。

然后,如果您将Unit放在某个Code B函数中(就像您在Int中所做的那样),就不会有任何错误。

示例

如果您想将Code C“转换”为Int,可以执行以下操作:

StringBuilder

猜猜没有问题。

第二个例子也是绝对正确的。

fun toStringBuilder(i: Int?): StringBuilder {
    val result = i?.toString() ?: ""
    return StringBuilder(result)
}

如果参数值为fun toStringBuilder(i: Int?): StringBuilder { val result = i?.toString() ?: return StringBuilder() return StringBuilder(result) } ,则函数将不会到达第二行,因为它将首先返回。

第三个例子会产生错误(例如你的null)。

Code B

同样,语法中没有错误。猫王的经营者是对的。错误是因为您尝试将fun toStringBuilder(i: Int?): StringBuilder { val result = i?.toString() ?: return "" return StringBuilder(result) } 返回到声明为返回String的函数。