Что это ? означает в этом случае? [Дубликат]

Позвольте мне сначала сказать сходство между методом, украшенным с помощью метода @classmethod vs @staticmethod.

Сходство: оба они могут быть вызваны самим классом Class , а не только экземпляр класса. Таким образом, оба они в некотором смысле являются методами класса .

Разница: класс-метод получит сам класс как первый аргумент, в то время как staticmethod не делает.

Таким образом, статический метод, в некотором смысле, не связан с самим классом и просто висит там только потому, что может иметь связанную функциональность.

>>> class Klaus:
        @classmethod
        def classmthd(*args):
            return args

        @staticmethod
        def staticmthd(*args):
            return args

# 1. Call classmethod without any arg
>>> Klaus.classmthd()  
(__main__.Klaus,)  # the class gets passed as the first argument

# 2. Call classmethod with 1 arg
>>> Klaus.classmthd('chumma')
(__main__.Klaus, 'chumma')

# 3. Call staticmethod without any arg
>>> Klaus.staticmthd()  
()

# 4. Call staticmethod with 1 arg
>>> Klaus.staticmthd('chumma')
('chumma',)
123
задан Marty Pitt 7 March 2013 в 03:36
поделиться

9 ответов

Я не могу найти никакой ссылки на него в спецификации языка для языка программирования .

Что касается вызова этого оператора в CoffeeScript, он называется экзистенциальным оператором ( в частности, «вариант доступа» экзистенциального оператора.

Из Документация CoffeeScript по операторам :

Вариант доступа для экзистенциального оператора ?. может использоваться для впитывания нулевых ссылок в цепочке свойств. Используйте его вместо доступа к точкам . в случаях, когда базовое значение может быть нулевым или неопределенным.

Таким образом, вариант доступа экзистенциального оператора, как представляется, является правильным способом ссылки к этому оператору; и TypeScript в настоящее время не поддерживает его (хотя другие выразили желание использовать эту функциональность ).

57
ответ дан DoNot 23 August 2018 в 23:38
поделиться

Не так хорошо, как сингл?, но он работает:

var thing = foo && foo.bar || null;

Вы можете использовать как можно больше & amp; & amp; как вам нравится:

var thing = foo && foo.bar && foo.bar.check && foo.bar.check.x || null;
78
ответ дан A. K-R 23 August 2018 в 23:38
поделиться

На github есть открытый запрос функции, где вы можете озвучить свое мнение / желание: https://github.com/Microsoft/TypeScript/issues/16

27
ответ дан basarat 23 August 2018 в 23:38
поделиться

Как уже было сказано, в настоящее время все еще рассматривается, но уже несколько лет мертв в воде .

Основываясь на существующих ответах, вот наиболее краткое руководство версия Я могу думать:

jsfiddle

function val<T>(valueSupplier: () => T): T {
  try { return valueSupplier(); } catch (err) { return undefined; }
}

let obj1: { a?: { b?: string }} = { a: { b: 'c' } };
console.log(val(() => obj1.a.b)); // 'c'

obj1 = { a: {} };
console.log(val(() => obj1.a.b)); // undefined
console.log(val(() => obj1.a.b) || 'Nothing'); // 'Nothing'

obj1 = {};
console.log(val(() => obj1.a.b) || 'Nothing'); // 'Nothing'

obj1 = null;
console.log(val(() => obj1.a.b) || 'Nothing'); // 'Nothing'

Он просто бесшумно выходит из строя при отсутствии ошибок свойств. Он возвращается к стандартному синтаксису для определения значения по умолчанию, которое также может быть опущено полностью.


Хотя это работает для простых случаев, если вам нужны более сложные вещи, такие как вызов функции, а затем получить доступ к свойству на результат, тогда любые другие ошибки также проглатываются. Плохой дизайн.

В приведенном выше случае оптимизированная версия другого ответа, размещенного здесь, является лучшим вариантом:

jsfiddle

function o<T>(obj?: T, def: T = {} as T): T {
    return obj || def;
}

let obj1: { a?: { b?: string }} = { a: { b: 'c' } };
console.log(o(o(o(obj1).a)).b); // 'c'

obj1 = { a: {} };
console.log(o(o(o(obj1).a)).b); // undefined
console.log(o(o(o(obj1).a)).b || 'Nothing'); // 'Nothing'

obj1 = {};
console.log(o(o(o(obj1).a)).b || 'Nothing'); // 'Nothing'

obj1 = null;
console.log(o(o(o(obj1).a)).b || 'Nothing'); // 'Nothing'

Более сложный пример:

o(foo(), []).map((n) => n.id)

Вы также можете пойти другим способом и использовать что-то вроде Lodash ' _.get() . Это кратким, но компилятор не сможет судить о действительности используемых свойств:

console.log(_.get(obj1, 'a.b.c'));
0
ответ дан Benny Bottema 23 August 2018 в 23:38
поделиться

Изменить: я обновил ответ благодаря комментарию fracz.

Выпущен TypeScript 2.0 !. Это не то же самое, что ?. (безопасный навигатор в C #)

Подробнее см. в этом ответе:

https://stackoverflow.com/a/38875179/1057052

Это будет только сообщать компилятору, что это значение не равно null или undefined. Это не проверяет, имеет ли значение значение null или undefined.

TypeScript Оператор с ненулевым утверждением

// Compiled with --strictNullChecks
function validateEntity(e?: Entity) {
    // Throw exception if e is null or invalid entity
}

function processEntity(e?: Entity) {
    validateEntity(e);
    let s = e!.name;  // Assert that e is non-null and access name
}
13
ответ дан Community 23 August 2018 в 23:38
поделиться

Мы создали этот метод util при работе над Phonetradr , который может дать вам безопасный доступ к глубоким свойствам с помощью TypScript:

/**
 * Type-safe access of deep property of an object
 *
 * @param obj                   Object to get deep property
 * @param unsafeDataOperation   Function that returns the deep property
 * @param valueIfFail           Value to return in case if there is no such property
 */
export function getInSafe<O,T>(obj: O, unsafeDataOperation: (x: O) => T, valueIfFail?: any) : T {
    try {
        return unsafeDataOperation(obj)
    } catch (error) {
        return valueIfFail;
    }
}

//Example usage:
getInSafe(sellTicket, x => x.phoneDetails.imeiNumber, '');

//Example from above
getInSafe(foo, x => x.bar.check, null);

1
ответ дан phidias 23 August 2018 в 23:38
поделиться

Это определено в спецификации ECMAScript Optional Chaining, поэтому мы должны, вероятно, сослаться на опциональную цепочку , когда мы обсудим это. Вероятная реализация:

const result = a?.b?.c;

Длинным и коротким из этого является то, что команда TypeScript ожидает, что спецификация ECMAScript будет затянута, поэтому их реализация может быть неразрывной в будущем. Если они что-то реализуют сейчас, в случае необходимости ECMAScript потребует серьезных изменений, если ECMAScript переопределит их спецификацию.

См. Дополнительная спецификация цепочки

Где-то никогда не будет быть стандартным JavaScript, команда TypeScript может реализовать по своему усмотрению, но для будущих дополнений ECMAScript они хотят сохранить семантику, даже если они дают ранний доступ, как и для многих других функций.

Short Cuts

Таким образом, доступны все java-скрипты JavaScripts, включая преобразования типов, такие как ...

var n: number = +myString; // convert to number
var b: bool = !!myString; // convert to bool

Ручное решение

Но вернемся к вопросу. У меня есть тупой пример того, как вы можете сделать аналогичную вещь в JavaScript (и, следовательно, в TypeScript), хотя я определенно не предполагаю, что это изящно, как функция, которую вы действительно выполняете.

(foo||{}).bar;

So если foo - undefined, результат будет undefined, и если foo определено и имеет свойство с именем bar, которое имеет значение, результатом будет это значение.

Пример в JSFiddle .

Это выглядит довольно отрывочно для более длинных примеров.

var postCode = ((person||{}).address||{}).postcode;

Функция цепочки

Если вы отчаянно нуждаетесь в более короткая версия, пока спецификация все еще находится в воздухе, я использую этот метод в некоторых случаях. Он оценивает выражение и возвращает значение по умолчанию, если цепочка не может быть удовлетворена или заканчивается нулевым / неопределенным (обратите внимание, что != здесь важна, мы не хотим использовать !== как мы хотим немного позитивного манипулирования здесь).

function chain<T>(exp: () => T, d: T) {
    try {
        let val = exp();
        if (val != null) {
            return val;
        }
    } catch { }
    return d;
}

let obj1: { a?: { b?: string }} = {
    a: {
        b: 'c'
    }
};

// 'c'
console.log(chain(() => obj1.a.b, 'Nothing'));

obj1 = {
    a: {}
};

// 'Nothing'
console.log(chain(() => obj1.a.b, 'Nothing'));

obj1 = {};

// 'Nothing'
console.log(chain(() => obj1.a.b, 'Nothing'));

obj1 = null;

// 'Nothing'
console.log(chain(() => obj1.a.b, 'Nothing'));
32
ответ дан user75525 23 August 2018 в 23:38
поделиться

Оператор ?. не поддерживается в TypeScript версии 2.0.

Поэтому я использую следующую функцию:

export function o<T>(someObject: T, defaultValue: T = {} as T) : T {
    if (typeof someObject === 'undefined' || someObject === null)
        return defaultValue;
    else
        return someObject;
}

использование выглядит следующим образом:

o(o(o(test).prop1).prop2

plus, вы можете установить значение по умолчанию:

o(o(o(o(test).prop1).prop2, "none")

Он отлично работает с IntelliSense в Visual Studio.

5
ответ дан VeganHunter 23 August 2018 в 23:38
поделиться

В версии 2.9 поддерживается! https://github.com/Microsoft/TypeScript/wiki/What%27s-new-in-TypeScript#non-null-assertion-operator

const a = {}
console.log(a!.b!.c)

no any дополнительные параметры, необходимые в .tsconfig

-1
ответ дан vladimir.shein 23 August 2018 в 23:38
поделиться
Другие вопросы по тегам:

Похожие вопросы: