如何在swift3中从Any获取String

air*_*aft 5 ios swift swift3

比如我得到一个dic来自fetchData:

(lldb) po dic

? 3 elements
  ? 0 : 2 elements
    - .0 : "total"
    - .1 : 0.00
  ? 1 : 2 elements
    - .0 : "year"
    - .1 : 2016
  ? 2 : 2 elements
    - .0 : "month"
    - .1 : 12

(lldb) po dic["year"]
? Optional<Any>


(lldb) po dic["year"]!
2016
Run Code Online (Sandbox Code Playgroud)

是否有String形式的功能Any

该函数的用法如下:

let total = UtilSwift.getStrFromAny(dic["total"] as Any )
Run Code Online (Sandbox Code Playgroud)

objective-c,我写了一个方法:

+ (NSString*)getStringWithoutNull:(id)value
{
    NSString *strValue = @"";
   if(value != nil){
        strValue = [NSString stringWithFormat:@"%@", value];
    }

    if([strValue isEqualToString:@"null"])
    {
        return @"";
    }

    if ([strValue isEqual:[NSNull null]]) {

        return @"";
    }

    return strValue;
}
Run Code Online (Sandbox Code Playgroud)

是否swift可以写一个这样的方法来获得String形式Any


Any也许Int,String,"",Double,或其他类型.


编辑 - 1

试过后Playground.:

import UIKit

let dict:[String:Any]  = ["aa": 123, "year":1994, "month":"12"]

let string = String(describing:dict["year"]) ?? ""   // Try to turn result into a String, o

print(string)  // If I print(string!), and there will report error.
Run Code Online (Sandbox Code Playgroud)

警告:

考试


编辑2

我知道edit -2也许画百合,但如果使用func下面的,当我传递一个Opitional值时func,返回String也将Opitinal如此,如何避免呢?

以下是我的测试Playground,dic["b"] as Any将参数转换为Opitional:

   let dic:[String:Any] = [  // ["b": 12, "A": "A"]

    "A":"A",
    "b":12
]

func stringFromAny(_ value:Any?) -> String {

    if let nonNil = value, !(nonNil is NSNull) {

        return String(describing: nonNil) // "Optional(12)"
    }
    return ""
}

let str = stringFromAny(dic["b"] as Any)  // "Optional(12)"
Run Code Online (Sandbox Code Playgroud)

Dan*_*all 8

试试这个:

func stringFromAny(_ value:Any?) -> String {
    if let nonNil = value, !(nonNil is NSNull) {
        return String(describing: nonNil)
    }
    return ""
}
Run Code Online (Sandbox Code Playgroud)

更新:

如果调用代码使用Any?显式转换为的参数调用上述函数Any(Swift 3编译器允许的奇怪场景),那么它将认为参数的最终类型是非可选的可选,即一个Any值类型Any代表的是Any?.或者,换句话说,该值将被视为Optional<Any>.some(value:Any?).

在这种情况下,if let解包"some"的情况会返回一个可选值作为函数实现中的结果.这意味着最终的字符串描述将包含"可选"标识.

由于Swift 3编译器很乐意在它之间进行转换Any并且Any?将类型的值视为类型Any的值,Any?反之亦然,因此检测实际上是否Any包含"Any" 实际上非常复杂.或不,并相应地解开.

下面提供了该功能的一个版本以及一些必要的附加扩展.此版本将以递归方式展平Any包含任意数量嵌套Any?案例的值,以检索最内层的非可选值.

虽然这是你似乎正在寻找的东西,但我认为解决程序员不应该做的事情是很麻烦的,即误导一个已知Any?值,Any因为编译器有一个奇怪的例外.即使它实际上并非如此.

这是代码的"开发人员证明"版本:

protocol OptionalType {
    var unsafelyUnwrapped: Any { get }
    var unsafelyFlattened: Any { get }
}

extension Optional: OptionalType {
    var unsafelyUnwrapped: Any { return self.unsafelyUnwrapped }
    var unsafelyFlattened: Any { return (self.unsafelyUnwrapped as? OptionalType)?.unsafelyFlattened ?? self.unsafelyUnwrapped }
}

func stringFromAny(_ value:Any?) -> String {
    switch value {
    case .some(let wrapped):
        if let notNil =  wrapped as? OptionalType, !(notNil.unsafelyFlattened is NSNull) {
            return String(describing: notNil.unsafelyFlattened)
        } else if !(wrapped is OptionalType) {
            return String(describing: wrapped)
        }
        return ""
    case .none :
        return ""
    }
}
Run Code Online (Sandbox Code Playgroud)