我在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一样,我不知道为什么它可以!!!!
答案 0 :(得分:3)
来自Kotlin's doc:
如果
?:
左侧的表达式不为null,则elvis运算符返回它,否则返回右侧的表达式。请注意,由于throw
和return
是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
的函数。