Swift 参数类型';xxx和x27;不符合预期的类型'_可格式化的';

Swift 参数类型';xxx和x27;不符合预期的类型'_可格式化的';,swift,swiftui,Swift,Swiftui,在使用SwiftUI时,我遇到了两个意外错误: import SwiftUI struct MyStruct: CustomStringConvertible { var description: String { "hello" } } class MyClass: CustomStringConvertible { var description: String { "hi" } } let a = MyStruct() let

在使用SwiftUI时,我遇到了两个意外错误:

import SwiftUI

struct MyStruct: CustomStringConvertible {
    var description: String { "hello" }
}

class MyClass: CustomStringConvertible {
    var description: String { "hi" }
}

let a = MyStruct()
let b = MyClass()
let s1 = "\(a)"        // hello
let s2 = "\(b)"        // hi

// ❌ Argument type 'MyStruct' does not conform to
//    expected type '_FormatSpecifiable'
let text1 = Text("\(a)")

// ❌ Cannot convert value of type 'MyClass' to
//    expected argument type 'String'
let text2 = Text("\(b)")

let n = 1

// ✅ this one is OK, why?
let text3 = Text("\(n)")

有人知道这些错误是什么意思吗?为什么前两个
Text
s不起作用,但最后一个没问题?谢谢。

这意味着
Text
没有与这些情况匹配的构造函数,请改用

let text1 = Text(String("\(a)"))
let text2 = Text(String("\(b)"))
使用Xcode 12.1/iOS 14.1测试,而不是:

let text1 = Text("\(a)")
做:

对另一个进行同样的操作。

问题 符合
CustomStringConvertible
允许您自定义
说明
,以后可以使用
字符串(说明:)
访问该说明:

不过,请致电:

let text1 = Text("\(a)")
您实际上是在调用此构造函数:

public init(_ key: LocalizedStringKey, tableName: String? = nil, bundle: Bundle? = nil, comment: StaticString? = nil)
请注意,
“\(a)”
不是一个
字符串
——它是一个
本地化字符串键

错误 参数类型“MyStruct”不符合预期类型 “\u FormatSpecifiable”

LocalizedStringKey
已符合
ExpressibleByStringInterpolation
,但其内部结构(
StringInterpolation
)没有接受类型为
MyStruct
的参数的方法

解决方案 您需要手动创建扩展以接受
MyStruct
参数:

extension LocalizedStringKey.StringInterpolation {
    mutating func appendInterpolation(_ value: MyStruct) {
        appendInterpolation(String(describing: value))
    }
}
现在你可以打电话:

let text1 = Text("\(a)")

或者,您可以使用不同的init来确保传递的是
字符串,而不是
LocalizedStringKey

@available(iOS 13.0, OSX 10.15, tvOS 13.0, watchOS 6.0, *)
@frozen public struct LocalizedStringKey : Swift.Equatable, Swift.ExpressibleByStringInterpolation {
  ...
  public struct StringInterpolation : Swift.StringInterpolationProtocol {
    public init(literalCapacity: Swift.Int, interpolationCount: Swift.Int)
    public mutating func appendLiteral(_ literal: Swift.String)
    public mutating func appendInterpolation(_ string: Swift.String)
    public mutating func appendInterpolation<Subject>(_ subject: Subject, formatter: Foundation.Formatter? = nil) where Subject : Foundation.ReferenceConvertible
    public mutating func appendInterpolation<Subject>(_ subject: Subject, formatter: Foundation.Formatter? = nil) where Subject : ObjectiveC.NSObject
    public mutating func appendInterpolation<T>(_ value: T) where T : SwiftUI._FormatSpecifiable
    public mutating func appendInterpolation<T>(_ value: T, specifier: Swift.String) where T : SwiftUI._FormatSpecifiable
    @available(iOS 14.0, OSX 11.0, tvOS 14.0, watchOS 7.0, *)
    public mutating func appendInterpolation(_ text: SwiftUI.Text)
    public typealias StringLiteralType = Swift.String
  }
  ...
}
let text1 = Text(verbatim: "\(a)")

有用链接:


但是我很困惑,
“\(a)”
“\(b)”
不是已经
字符串了吗?
extension LocalizedStringKey.StringInterpolation {
    mutating func appendInterpolation(_ value: MyStruct) {
        appendInterpolation(String(describing: value))
    }
}
let text1 = Text("\(a)")
let text1 = Text(verbatim: "\(a)")