如何用Codable类型定义变量?

时间:2017-10-04 12:15:21

标签: json swift swift4 swift-protocols

我想创建类型为 Codable 的变量。然后在JSONEncoder类中使用它。我认为下面的代码应该可以正常工作,但它给了我错误:

  

无法使用encode类型的参数列表调用(Codable)

如何声明JSONEncoder可以无错误地使用的可编码变量?

struct Me: Codable {
    let id: Int
    let name: String
}

var codable: Codable? // It must be generic type, but not Me.

codable = Me(id: 1, name: "Kobra")

let data = try? JSONEncoder().encode(codable!)

Here是如何使用函数传递Codable的类似问题。但我正在寻找如何使用变量(类变量)设置Codable。

3 个答案:

答案 0 :(得分:6)

您的代码没问题,我们唯一需要关注的是Codable

Codable是一个typealias,它不会为您提供通用类型。

JSONEncoder()。编码(Generic confirming to Encodable)。

所以,我修改了下面的代码,它可能对你有帮助..

protocol Codability: Codable {}

extension Codability {
    typealias T = Self
    func encode() -> Data? {
        return try? JSONEncoder().encode(self)
    }

    static func decode(data: Data) -> T? {
        return try? JSONDecoder().decode(T.self, from: data)
    }
}

struct Me: Codability
{
    let id: Int
    let name: String
}

struct You: Codability
{
    let id: Int
    let name: String
}

class ViewController: UIViewController
{
    override func viewDidLoad()
    {
        var codable: Codability
        codable = Me(id: 1, name: "Kobra")
        let data1 = codable.encode()

    codable = You(id: 2, name: "Kobra")
    let data2 = codable.encode()
}
}

答案 1 :(得分:4)

我创建了与您相同的场景:

struct Me: Codable
{
    let id: Int
    let name: String
}

struct You: Codable
{
    let id: Int
    let name: String
}

class ViewController: UIViewController
{
    override func viewDidLoad()
    {
        var codable: Codable?

        codable = Me(id: 1, name: "Kobra")
        let data1 = try? JSONEncoder().encode(codable)

        codable = You(id: 2, name: "Kobra")
        let data2 = try? JSONEncoder().encode(codable)
    }
}

上面的代码没有给我任何错误。我唯一改变的是:

let data = try? JSONEncoder().encode(codable!)

我没有解开codable并且工作正常。

答案 2 :(得分:1)

我用过这种方式,也许对你的情况也有帮助。

    public Localizer T
    {
        get
        {
            if (_localizationService == null)
                _localizationService = EngineContext.Current.Resolve<ILocalizationService>();

            if (_localizer == null)
            {
                _localizer = (format, args) =>
                {
                    var resFormat = _localizationService.GetResource(format);
                    if (string.IsNullOrEmpty(resFormat))
                    {
                        return new LocalizedString(format);
                    }
                    return new LocalizedString((args == null || args.Length == 0)
                        ? resFormat
                        : string.Format(resFormat, args));
                };
            }
            return _localizer;
        }
    }

然后创建了一个方法:

public protocol AbstractMessage: Codable {
  var id: Int { get } // you might add {set} as well
  var name: Int { get }
}

在这里,我创建了一个通用协议,并将其作为通用类型传递给我的函数。