从可选中获取对象类型?

时间:2015-12-08 07:29:03

标签: swift

是否可以从可选项中获取对象类型?

例如,如果我有一个具有可选字符串属性的类,我可以以某种方式返回字符串类型吗?

我拥有的确切用例是我有许多自定义类,所有自定义类都有一个属性,它将另一个自定义类存储为可选值。我想编写一个泛型函数,它将创建存储在optional。

中的对象类的实例

这是我正在寻找的一个例子,虽然.dynamicType不起作用,因为它是可选的:

a = Categorization.where(category_id: @category_id)

3 个答案:

答案 0 :(得分:1)

您只需要检查是否存在可选项:

func myFunc(c: Class2) -> Class1? {
    if let c1 = c.myOp{
      return c1.dynamicType()
    }
    return nil
}

OR

 func myFunc(c: Class2) -> Class1? {
        if c.myOp != nil{
          return c.myOp!.dynamicType()
        }
        return nil
    }

请注意,您的返回类型也必须是可选的。

答案 1 :(得分:1)

因为你想在Generics中使用它,我试过你。它有效,但它可能没那么有用。

首先进行一些设置:

这是一个辅助协议,用于确保我们的Generic类型具有已知的init方法。

protocol ZeroParameterInit {
    init()
}

这是从可选项中获取类型的扩展名:

extension Optional {

    var dynamicWrappedType : Wrapped.Type {
        return Wrapped.self
    }
}

在您的代码中实施:

class Class1 : ZeroParameterInit {
    required init() {}
}

class Class2 {
    var myOp: Class1?
}

var c = Class2()
c.myOp = c.myOp.dynamicWrappedType.init()

通用实施:

class Class1 : ZeroParameterInit {
    required init() {}
}

class Class2<T where T : ZeroParameterInit> {
    var attribute: Optional<T>// used long syntax to remind you of : Optional<Wrapped>
    init(attr:T) {
        attribute = attr
        attribute = nil
    }
}

创建实例的功能:

func myFunc<T>(instance: Class2<T>) -> T {

    return instance.attribute.dynamicWrappedType.init()

}

一些测试:

let alpha = Class1()
let beta = Class2(attr: alpha)
beta.attribute = myFunc(beta)

问题:

您无法在不通知其类型的通用属性的情况下创建Class2的实例。所以你需要传递一些对象/类型,这会使事情再次复杂化。

一些可能改善其运作方式的额外方法:

init() {
}

let delta = Class2<Class1>()
delta.attribute = myFunc(delta)
init(type:T.Type) {
}

let epsilon = Class2(type: Class1.self)
epsilon.attribute = myFunc(epsilon)

答案 2 :(得分:0)

在模拟器中尝试过,如果我理解你,似乎做正确的事情

@BasePathAwareController
@RequestMapping("/users")
public class RestApiController implements ResourceProcessor<Resource<User>>{
    @Autowired
    private EntityLinks entityLinks;

    @RequestMapping(method=RequestMethod.POST)
    @ResponseBody
    public ResponseEntity<Resource<User>> saveUser(@Param("name") String name) {
        // Testing
        System.out.println(name);
        Resource<User> resource = new Resource<>(new User());
        return new ResponseEntity<>(resource , HttpStatus.OK);
    }

    @Override
    public Resource<User> process(Resource<User> resource) {
            LinkBuilder lb = entityLinks.linkFor(User.class);
            resource.add(new Link(lb.toString()));
        return resource;
    }
}