我90%肯定这是预期的行为,但在这种情况下,我只是想接受教育!
在我的项目中,我已经定义了一个温度结构,符合IntegerLiteralConvertible协议:
struct Temperature {
var kelvin: Int
var celcius: Int { get { ... } }
var fahrenheit: Int { get { ... } }
}
extension Temperature: IntegerLiteralConvertible {
init(integerLiteral value: IntegerLiteralType) {
kelvin = value
}
}
现在一切正常,因为我在创建温度实例时会有所期待:
let absoluteZero: Temperature = 0
但是如果我在定义的函数中返回Int
以返回Temperature
,即
func randomTemperature() -> Temperature {
return random()
}
我将收到错误消息:"无法转换类型' Int'的返回表达式返回类型'温度'
直观地说,我希望从Temperature
推断返回的类型Int
,因此IntegerLiteralConvertible。
在文档中挖掘一下(或现在开源代码:D!),我发现Int结构符合继承自IntegerLiteralConvertible的SignedNumberType。我怀疑问题的答案与此有关。
那么,为什么?
提前致谢! (在此期间我会继续挖掘)
答案 0 :(得分:2)
在上述评论中进行了一些讨论之后,我意识到你想要问的是:
randomTemperature() -> Temperature
value属性作为返回类型发送时int
方法失败?在代码中:
func randomTemperature() -> Temperature {
let anyInt = 1
return anyInt
// Error: "Cannot convert return expression of
// type 'Int' to return type 'Temperature'
}
简短的回答是:你不能将'Int'类型转换为返回类型Temperature'
(作为错误状态)。你问,你的初始化器怎么样? Temperature: IntegerLiteralConvertible
初始化函数init(integerLiteral value: IntegerLiteralType)
仅适用于文字(IntegerLiteralType
),整数不是文字。
如需更全面的答案,请参阅下文。
来自Apple`s documentation on literals,它说
文字是类型值的源代码表示,例如 作为数字或字符串。
...
文字本身没有类型。相反,文字被解析为具有无限精度和Swift的类型推断 试图推断文字的类型。
...
为文字值指定类型注释时, 注释的类型必须是可以从中实例化的类型 字面值。也就是说,类型必须符合其中之一 遵循Swift标准库协议: 整数文字的 IntegerLiteralConvertible ......
来自Apple关于IntegerLiteralConvertible
协议的文档:
可以使用整数文字初始化符合类型。
好的,所以字面上永远不会有自己的类型。这样可以解决问题。
在Temperature
结构中考虑Double
类型,这种类型也符合IntegerLiteralConvertible
。
对于Double
,我们有:
func someDouble() -> Double {
return 1 // This is ok, "1" here is a literal, and the return
// of type Double can be initialised via the literal
}
func someDoubleTrouble() -> Double {
let anyInt = 1
return anyInt // Error! anyInt is not a literal, but an Int type,
// and return typ expects Double (or literal).
}
// The same applies for these
var someInt = 1
var anotherDouble: Double = 1 // ok, as above, literal
var anotherDoubleTrouble: Double = someInt // Error!
完全相同适用于您的Temperature
结构类型。
func someTemperature() -> Temperature {
return 1 // Ok
}
func someTroubledTemperature() -> Temperature {
let myInt = 1
return myInt // Error!
}
// The same applies for these
var someInt = 1
var anotherTemperature: Temperature = 1 // ok, as above, literal
var anotherTroubledTemperature: Temperature = someInt // Error!
答案 1 :(得分:1)
看来我从根本上误解了Swift中的类型系统。 IntegerLiteralConvertible
代表Temperature
,其他'LiteralConvertible'类型对称:
“符合类型可以用整数文字初始化。”
编程中的文字通常是源代码中定义的常量。直接从documentation:
“文字是类型值的源代码表示,例如数字或字符串。”
因此,我现在知道为什么我的Int
类型不能用Int
初始化,而不是整数文字,IntegerLiteralConvertible
只是一个结构本身符合{{1}}协议。似乎“可转换性”不是双向发生的(或者至少不是由语法分析器动态推断的)。