Why would you use the ternary operator without assigning a value for the “true” condition (x = x ?: 1)

前端 未结 7 1650
旧时难觅i
旧时难觅i 2020-12-03 09:38

In the Android open-source qemu code I ran across this line of code:

machine->max_cpus = machine->max_cpus ?: 1; /* Default to UP */

7条回答
  •  独厮守ぢ
    2020-12-03 10:25

    There's another useful case for this -- the elimination of intermediate variables when calling a function or method that might return nil, that we wish to avoid calling twice. For example (Objective-C), suppose we want to unpack a file into an array if it exists, otherwise return an empty array.

    - (NSArray*)hydrateBacklogFromFile:(NSString *path)
    {
        NSArray *backlog = @[];
        NSData *backlogData = [NSData dataWithContentsOfFile:path];
        if (backlogData)
        {
            backlog = [NSKeyedUnarchiver unarchiveObjectWithData:backlogData] ?: backlog;
        }
        return backlog;
    }
    

    The alternatives are less concise.

    - (NSArray*)hydrateBacklogFromFile:(NSString *path)
    {
        NSArray *backlog = @[];
        NSData *backlogData = [NSData dataWithContentsOfFile:path];
        if (backlogData)
        {
            NSArray *tempArray = [NSKeyedUnarchiver unarchiveObjectWithData:backlogData];
            if (tempArray != nil)
            {
                backlog = tempArray;
            }
        }
        return backlog;
    }
    

    Or uglier with multiple returns etc.

    - (NSArray*)hydrateBacklogFromFile:(NSString *path)
    {
        NSData *backlogData = [NSData dataWithContentsOfFile:path];
        if (backlogData)
        {
            NSArray *tempArray = [NSKeyedUnarchiver unarchiveObjectWithData:backlogData];
            if (tempArray != nil)
            {
                return tempArray;
            }
        }
        return @[];
    }
    

    So it's useful syntactic sugar that I find fairly readable. The downsides are

    • Implicit conversion of a pointer to a bool. This is a long-standing C convention, but most modern languages disallow it, complicating any porting efforts.

    • As others have said it's also a non-standard extension, so it should be avoided if portability is a consideration at all.

提交回复
热议问题