def line(line, types, null_value=None, columns=None):
    """
    Parses a tsv line
    :param line: The line to parse
    :param types: fields types
    :param null_value: value to interpret as a None
    :param columns: which columns to return
    :return: selected columns
    """
    assert columns is None or len(types) == len(columns)
    fields = line.rstrip('\n').split('\t')
    flen = len(fields)
    res = list()
    for i, vtype in enumerate(types):
        if columns is not None:
            index = columns[i]
        else:
            index = i
        if index < flen:
            field = fields[index]
        else:
            field = null_value
        if i < flen and (null_value is None or field != null_value):
            field = vtype(field)
        else:
            field = None
        res += [field]
    return tuple(res)
